runCommand vs aggregate方法进行聚合

dsh*_*rew 2 mongodb aggregation-framework runcommand

要运行聚合查询,可以使用以下任一方法:

db.collectionName.aggregate(query1);
Run Code Online (Sandbox Code Playgroud)

要么

db.runCommand(query2)
Run Code Online (Sandbox Code Playgroud)

但是今天早上我注意到了一些奇怪的事情.这个:

db.runCommand(

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


         }
      }

   ]
});
Run Code Online (Sandbox Code Playgroud)

失败并出错:

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

这个:

db.collectionName.aggregate([

{
  $match: {
           field: param
   }
}

]) 
Run Code Online (Sandbox Code Playgroud)

正在工作(给出预期的聚合结果).

这怎么可能?

Nei*_*unn 5

当然,不同之处在于该.aggregate()方法返回一个"光标",而您提供的选项runCommand()则不然.这实际上是遗留形式,它将响应作为单个BSON文档返回,并具有所有限制.另一方面,游标没有限制.

当然你可以使用这个runCommand()方法用shell"制作你自己的光标",因为后来所有这正是.aggregate()方法在"幕后"做的事情.所有驱动程序都是如此,它基本上为所有内容调用数据库命令.

使用shell,您可以像这样转换您的请求:

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
Run Code Online (Sandbox Code Playgroud)

如果你真的想深入研究它,那么输入db.collectionName.aggregate没有括号,()所以你实际上打印功能定义.这将向您展示一些其他函数调用,您可以进一步深入研究它们,并最终看到上面显示的有效线条,以及许多其他内容.

但是你运行它的方式,它是一个"单BSON文档"响应.按照此处显示的方式运行它,您将获得相同的"光标"响应.