MongoCursorException — Курсор не найден (Драйвер PHP MongoDB)

Код:

try {
$documentsFind = $client->$db->$collection->find([
// query
]);
if ($documentsFind) {
foreach ($documentsFind as $product) {
// code...
}
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}

ошибка:

Фатальная ошибка: Uncaught MongoDB \ Driver \ Exception \ RuntimeException:
Курсор не найден, идентификатор курсора: 31837896248 в …

Кажется, что курсор существует, но время ожидания истекло? Как я могу предотвратить это?

Отредактировано, чтобы добавитьЯ пытался делать:

 if ($documentsFind) {
$documentsFind->immortal(true); // keep alive
foreach ($documentsFind as $product) {
// code...
}
}

Но это приводит к Call to undefined method MongoDB\Driver\Cursor::immortal(),

2

Решение

Попробуйте сделать запрос следующим образом:

$documentsFind = $client->$db->$collection->find([
// query
], ['noCursorTimeout' => true]);

find() метод передает второй аргумент Find конструктор класса, чтобы вы могли видеть все доступные опции Вот

4

Другие решения

Исключение курсора говорит,

Драйвер пытался получить больше результатов из базы данных, но в базе данных не было записи запроса. Обычно это означает, что время ожидания курсора на стороне сервера истекло: после нескольких минут бездействия база данных уничтожит курсор.

PHP-драйвер MongoDB имеет два разных времени ожидания:

  1. Время соединения вышло
  2. Тайм-аут курсора

Убедитесь, что вы используете тайм-аут или бессмертный курсор:

$cursor = $collection->find();
$cursor->immortal(true);
$cursor->timeout(-1);

Замечания: Тайм-аут указывает время ожидания на стороне клиента, пока бессмертный устанавливает курсор на стороне сервера.

Но я хотел бы предложить, если у вас есть курсор большого размера данных, то вы должны получить данные курсора в виде блоков:

Получите первые 1000 документов из коллекции, обработайте их. Затем получите следующие 1000 документов. Вы можете сделать это путем пропуска и ограничения.

1