runCommand 与聚合方法进行聚合

runCommand vs aggregate method to do aggregation

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

db.collectionName.aggregate(query1);

db.runCommand(query2)

但是今天早上我注意到了一些奇怪的事情。虽然这样:

db.runCommand(

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


         }
      }

   ]
});

失败并出现错误:

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

这个:

db.collectionName.aggregate([

{
  $match: {
           field: param
   }
}

]) 

正在运行(给出预期的聚合结果)。

这怎么可能?

嘛区别当然是.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。另一方面,游标没有限制。

当然可以用runCommand() method to "make your own cursor" with the shell, since after-all that is exactly what the .aggregate()的方法做"under the covers"。所有驱动程序也是如此,它们本质上是为所有内容调用数据库命令。

使用 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

如果您真的想深入研究它,请输入不带括号 ()db.collectionName.aggregate,以便您实际打印函数定义。这将向您展示一些其他函数调用,您可以进一步深入研究它们,并最终了解上面显示的行以及许多其他内容的有效内容。

但是您 运行 的方式,是 "single BSON Document" 的回应。 运行 按照这里显示的方式,您会得到相同的 "cursor" 响应。