Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

runCommand vs aggregate method to do aggregation

To run aggregation query it is possible to use either of these:

db.collectionName.aggregate(query1);

OR

db.runCommand(query2)

But I noticed something bizarre this morning. While this:

db.runCommand(

{
   "aggregate":"collectionName",
    allowDiskUse: true,
   "pipeline":[
      {
         "$match":{
            "field":param


         }
      }

   ]
});

fails with error:

{
    "ok" : 0.0,
    "errmsg" : "aggregation result exceeds maximum document size (16MB)",
    "code" : 16389,
    "codeName" : "Location16389"
}

This:

db.collectionName.aggregate([

{
  $match: {
           field: param
   }
}

]) 

is working (gives the expected aggregation result).

How is this possible?

like image 787
dsharew Avatar asked Mar 06 '23 07:03

dsharew


1 Answers

Well the difference is of course that the .aggregate() method returns a "cursor", where as the options you are providing to runCommand() you are not. This actually was the legacy form which returned the response as a single BSON document with all it's limitations. Cursors on the other hand do not have the limitation.

Of course you can use the runCommand() method to "make your own cursor" with the shell, since after-all that is exactly what the .aggregate() method is doing "under the covers". The same goes for all drivers, which essentially invoke the database command for everything.

With the shell, you can transform your request like this:

var cmdRes = db.runReadCommand({
   "aggregate": "collectionName",
   "allowDiskUse": true,
   "pipeline":[
      {
         "$match":{
            "field":param
         }
      }
   ],
   "cursor": { "batchSize": 25 }
});

var cursor = new DBCommandCursor(db, cmdRes);

cursor.next();   // will actually iterate the cursor

If you really want to dig into it then type in db.collectionName.aggregate without the parenthesis () so you actually print the function definition. This will show you some other function calls and you can dig further into them and eventually see what is effectively the lines shown above, amongst a lot of other stuff.

But the way you ran it, it's a "single BSON Document" response. Run it the way shown here, and you get the same "cursor" response.

like image 183
Neil Lunn Avatar answered Mar 11 '23 03:03

Neil Lunn