Исключение Mongo-MongoCursor с PHP-драйвером MongoDB v1.6

У меня проблемы с PHP MongoCursor, так как я обновил драйвер PHP Mongo с 1.5.8 до 1.6.0

Следующий код хорошо работает с версией 1.5.8, но вылетает с версией 1.6

Версия PHP 5.5.21., Версия Apache — Apache / 2.4.10 (Ubuntu).

$mongoClient = new \MongoClient($serverUrl, ['readPreference'=>\MongoClient::RP_NEAREST]);
$database = $mongoClient->selectDB($dbName);
$collection = $database->selectCollection($collectionName);

// count() works fine and returns the right nb on documents
echo '<br/>count returned '.$collection->count();

// find() exectues with no error...
$cursor = $collection->find();
$documents = [];
// ...and hasNext() crashes with the Excetion below
while($cursor->hasNext()){$documents[] = $cursor->getNext();}
return $documents;

И поэтому вызов hasNext () завершается с этим сообщением:

КРИТИЧЕСКИЙ: MongoException: объект MongoCursor не был правильно инициализирован его конструктором (неперехваченное исключение) …

Я делаю что-то неправильно ?
Спасибо за помощь!

2

Решение

Это может быть связано с ошибкой, которая была введена в 1.6.0 относительно итерации с hasNext() а также getNext(): PHP-1382. С тех пор исправление было объединено с v1.6 ветка и должен быть выпущен позже на этой неделе как 1.6.1.

Тем не менее, ошибка, касающаяся hasNext() на самом деле последний документ в наборе результатов будет пропущен во время итерации. Если я запускаю ваш оригинальный скрипт против 1.6.0, массив содержит null значение как его последний элемент. После исправления массив будет содержать все документы, как и ожидалось. Я не могу воспроизвести исключение, которое вы видите с любой версией.

Это исключение фактически выдается из внутренних проверок структур данных C, чтобы гарантировать, что объект курсора должным образом связан с MongoClient и соединением с сокетом. Увидеть MONGO_CHECK_INITIALIZED() макро вызовы в этот файл. Большинство всех методов курсора проверяют, связан ли MongoClient, но hasNext() уникален тем, что он также проверяет объект сокета (я полагаю, что другие методы просто предполагают, что курсор с MongoClient также имеет сокет). Если это исключение действительно воспроизводимо для вас, и вы хотите выполнить некоторую отладку с расширением, мне было бы очень интересно узнать, какая из двух проверок выдает ошибку.


В качестве примечания вы должны также указать "replicaSet" опция при построении MongoClient. Это должно иметь имя набора реплик, которое гарантирует, что драйвер может должным образом игнорировать соединения с хостами, которые не являются членами предполагаемого набора реплик.

3

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

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

foreach( $cursor as $doc ) {
$documents[] = $doc;
}
1

Я искал пример кода, как реализовать настраиваемый курсор, и нашел этот вопрос. Следующий код представляет собой простой пример настраиваемого курсора (через переменную $ cursor), который вы предоставляете в ограниченной коллекции mongodb.

    $cursor->tailable(true);
$cursor->awaitData(true);
while (true) {
if ($cursor->hasNext()) {
var_dump($cursor->getNext());
} else {
if ($cursor->dead()) {
break;
}
}
}
1
По вопросам рекламы [email protected]