yii2 mongodb $cursor->toArray Работает слишком медленно -- как ускорить выборку больших объёмов данных из mongo в проложение

Вызов типа:

$cursor = \Yii::$app->mongodb->createCommand(\Yii::$app->mongodb->getQueryBuilder()->aggregate(
		$collection->name, $pipeline, 
		['allowDiskUse' => true, 'cursor' => ['batchSize' => $this->batchSize]]))->execute();

$resultArray = $cursor->toArray();

-- практически все время при большой выборке потратит на вызов toArray(), и это будет проходить медленно.

Итерируемся сами

Можно итерироваться по курсору, без вызова toArray(), но даже пустая итерация типа:

foreach ($cursor as $key => $report) {
	//$result2[] = $report;
	$a = 1;
}

-- заёмёт немало времени.

Как ускорить передачу данных

Чтобы ускорить дело, можно применить следующие подходы:

  1. Уменьшить число извлекаемых документов (если это для вас походит -- работайте с запросом агрегации)
  2. Уменьшите объём самого документа, перечислив только те поля, что вам нужны (для агрегации можно использовать $project)
  3. Попробуйте использовать сокеты вместо TCP/IP -- для передачи между монгой и приложением (это должно работать быстрее)
  4. Если используется allowDiskUse, то можно попробовать настроить выгрузку в такую папку, которая по факту лежит в оперативной памяти, что опять же, сильно ускорит процесс.

Источники:

  • https://stackoverflow.com/questions/44461679/is-there-option-to-convert-mongodb-cursor-to-array-quickly-with-php
  • https://github.com/yiisoft/yii2-mongodb/commit/9395f072c2bf220e4b62fb677f93542e9a53fffe
  • Баг репорт о предыдущей пробелеме: https://github.com/yiisoft/yii2-mongodb/issues/228

Key Words for FKN + antitotal forum (CS VSU):