[PHP] MongoDB 3.6 aggregateCursor issue

491 views
Skip to first unread message

Daniele Dv

unread,
Nov 30, 2017, 4:12:58 AM11/30/17
to mongodb-user
Hi. I've updated my MongoDB to the new 3.6 version. I'm using a MongoClient on a CentOS 7 OS with PHP 5.5.
If I run the first example reported in http://php.net/manual/en/mongocollection.aggregatecursor.php, now I have the following error message:

Uncaught exception 'MongoCursorException' with message '95.110.150.99:27017: the command cursor did not return a correctly structured response'


Do you have any idea about this behaviour?



Jeremy Mikola

unread,
Dec 1, 2017, 10:15:12 AM12/1/17
to mongod...@googlegroups.com
It looks like this exception comes from MongoCommandCursor::rewind(). The exception message actually appears twice in the driver, once when accessing the "cursor" document in the initial command response, and a second time when we attempt to access the "id", "firstBatch", and "ns" fields within that document. php_mongo_get_cursor_info() may report failure for various reasons, but some debugging revealed that the point of error is that the cursor "id" is not a 64-bit integer (here). When a command cursor has no more results (i.e. all results are contained in the "firstBatch" array of the initial command reply), the cursor "id" is zero. It looks like MongoDB 3.6 now returns zero as a 32-bit integer, where previous versions (3.4 and below) returned a 64-bit integer. The strict type checking in the driver is responsible for this error.

Note that the legacy "mongo" extension is no longer maintained, so this is not something that will be fixed. If possible, you should consider upgrading to the actively developed and maintained "mongodb" extension. A community-developed mongo-php-adapter library also exists, which implements the "mongo" API atop the new driver and can help ease the migration process. This is discussed in more detail on: https://docs.mongodb.com/ecosystem/drivers/php/

Alternatively, you may be able to work around this issue by manually changing the initial command response from "aggregate" before creating the command cursor. This entails running the command manually with MongoDB::command() and then constructing a command cursor from the result with MongoCommandCursor::createFromDocument(). Between those steps, we can check for 32-bit zero and manually replace it with a 64-bit type. Consider:

<?php

$m = new MongoClient;

$m->test->foo->drop();
$m->test->foo->insert(['x' => 1]);
$m->test->foo->insert(['x' => 2]);
$m->test->foo->insert(['x' => 3]);

$response = $m->test->command(
    [
        'aggregate' => 'foo',
        'pipeline' => [['$match' => ['x' => ['$gt' => 1]]]],
        'cursor' => (object) [],
    ],
    [], // options
    $hash // connection hash (output variable)
);

var_dump($response);

if ($response['cursor']['id'] === 0) {
    $response['cursor']['id'] = new MongoInt64('0');
}

$cursor = MongoCommandCursor::createFromDocument($m, $hash, $response);

var_dump(iterator_to_array($cursor));


Without the conversion, this produces the original exception you reported. With the conversion in place, cursor iteration proceeds as expected.

 



--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/d236be07-42a2-42c3-9c4a-b571432c3274%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages