PHP MongoDB - Use of the aggregate command without the cursor option is deprecated. What?
Asked Answered
D

7

10

I have updated mongo and now in the log the following error appears: Use of the aggregate command without the cursor option is deprecated

Mongo says that I should put a second REQUIRED parameter to aggregate function, because my current usage is deprecated.

I currently use the following code PHP (now is deprecated):

$this->db->{$collection}->aggregate($options);

And return this format:

{"result":[
    {
    "_id":"xxxxxx",
    "update":[
    {
    "firstUpdateTime":xxxxxx,
    "updateTime":xxxxxxx,
    }
    ],
    "media":[
    {
    "xxxx":{ ...

To not use an deprecated code I add the new second parameter (but I do not understand what to put):

$this->db->{$collection}->aggregate($options, array('cursor' => array('batchSize' => 101)));

And this returns the same information but varies the initial structure:

{"cursor":{
"id":{
"value":"xxxxxx"
},
"ns":"xxxxxx.instagram",
"firstBatch":[
{
"_id":"xxxxxx",
"update":[
{
"firstUpdateTime":xxxxxx,
"updateTime":xxxxxx,
}
],
"media":[
{
"xxxxxx":{ ...

After the update Mongo forces me to change the way I read the data. I don't understand what value I should put in that second parameter called "cursor"...

What should I put in that second parameter? Can I set a default value without altering the structure of results?

Doc: https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ http://php.net/manual/es/mongocollection.aggregate.php

UPDATE:

If I indicate the cursor in the function I no longer receive the error. But without applying to the solution, I read the LOG and the warning appears at random, I have a code that I run several times and sometimes if it reports the mentioned warning and others do not.

Why?

Dominik answered 6/5, 2017 at 10:27 Comment(2)
Can you please add the code including the log messages with and without cursor option that demonstrate the behavior you have mentioned in the update ?Trevethick
rerer to this post for cursor use.Pomerania
W
6

When you query something to MongoDB and you expect results, you will have this variable called cursor, which simply is a pointer to the document you currently did read. It is just like a scrollbar in the browser.

You can specify how many documents it should read into a buffer batchSize as you did with value 1.

It is useful when you know how much documents you expect to read. When you only need 10 documents, you can get all those in a single network packet using batchSize => 10. When specify batchSize => 5, it will take longer because it does take two network packets to the database to get the expected 10 documents.

You are safe using the default batchSize.

You can try to iterate over the cursor using foreach like in an example in the docs: http://php.net/manual/en/class.mongocommandcursor.php

Im not sure if the php.net documentation is up to date with the most current version of the MongoDB driver.

Watford answered 8/5, 2017 at 15:29 Comment(2)
So far I didn't have to worry about missing data since aggregate returns all the data. I understand that the batchSize figure is similar to a "limit" of a query. What's the cut if I give you 101? In my example of results, what would "the document" be? Thanks! @DanFromGermanyDominik
@Dominik the batchSize is not visible to the user but has impact on the network and memory because if your documents do not fit in the buffer, the client will call the server like "give me the next 101 documents" so it is not really a limit because you still get all the documents.Watford
T
3

You have to use aggregateCursor which returns the cursor row instead of results only.

Something like

The first batch is by default set at 101 results.

$cur = $this->db->{$collection}->aggregateCursor($pipeline);

Set the batchsize ( the second parameter from your question ) on aggregate cursor of 50 for subsequent batches. If you don't use below option the default will fetch around 4 MB.

$cur->batchSize( 50 );

You can now iterate and read results to get all documents.

The server will fetch initial(first) batch of 101 documents on first loop iteration followed by subsequent batch at 102 iteration and at intervals of 50 on rest of batches until you exhaust the cursor.

foreach ( $cur as $result )
{
   echo $result['_id'], "\n";
}

To control batch size for first batch, you can specify batchSize as cursor option but generally it is not needed.

$cur = $this->db->{$collection}->aggregateCursor($pipeline, 'cursor' => [ 'batchSize' => 1 ]);

Reference: https://derickrethans.nl/aggregation-cursor.html

Trevethick answered 9/5, 2017 at 3:4 Comment(0)
P
2

From the latest MongoDB manual the aggregate operation have changed.

aggregate without cursor

MongoDB 3.4 deprecates the use of aggregate command without the cursor option, unless the pipeline includes the explain option. When returning aggregation results inline using the aggregate command, specify the cursor option using the default batch size cursor: {} or specify the batch size in the cursor option cursor: { batchSize: }.

You can just specify that parameter for your function call with adding [ "cursor" => [ "batchSize" => 0 ] ] as the second parameter will solve this. refer here.

You can also refer to this SO question for the cursor parameter usage.

Pomerania answered 8/5, 2017 at 15:12 Comment(0)
S
2

Replace this :
$this->db->{$collection}->aggregate($options);

with below code by adding cursor array.
$this->db->{$collection}->aggregate($options,array('cursor'=>array('batchSize' => 1)));

Seabury answered 3/5, 2019 at 11:5 Comment(0)
S
1

Assuming you are using the latest MongoDB PHP Library, you should be able to pass 'useCursor' => false option (the default is true) as explained in the doc.

Scevo answered 8/5, 2017 at 11:15 Comment(2)
Thanks for replying but I'm not using MongoDB PHP Library I use the one that has no interface and this doc is not compatible with me. I use the referenced in the message, although this one has errors for not being updated at all.Dominik
The extension that you are currently using is already deprecated. So I don't think there is any easy way to have it support latest version of MongoDB. The doc suggests to use MongoDB driver in conjuction with MongoDB PHP Library insteadScevo
P
1

The driver mongo is deprecated and not support newest PHP major releases (PHP 7 for example).

New driver named as mongodb http://php.net/manual/en/set.mongodb.php

Preemie answered 10/5, 2017 at 9:27 Comment(0)
A
1
$command = new MongoDB\Driver\Command([
    'aggregate' => 'collection',
    'pipeline' => [
        ['$group' => ['_id' => '$y', 'sum' => ['$sum' => '$x']]],
    ],
    'cursor' => new stdClass, // Exactly what I need to fix the problem
]);
$cursor = $manager->executeCommand('db', $command);

Take a look at Example #2 https://www.php.net/manual/en/mongodb-driver-manager.executecommand.php

Alectryomancy answered 5/7, 2022 at 4:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.