Mongodb node.js $ out with aggregation仅在调用toArray()时有效

Mat*_*ann 7 mongodb node.js aggregation-framework

保存使用聚合查询"mongodb": "^3.0.6"与结果$out时调用运营商只工作.toArray().

聚合步骤:

let aggregationSteps = [{
    $group: {
        _id: '$created_at',
    }
}, {'$out': 'ProjectsByCreated'}];
Run Code Online (Sandbox Code Playgroud)

执行聚合:

await collection.aggregate(aggregationSteps, {'allowDiskUse': true})

预期结果:名为ProjectsByCreated的新集合.

结果:没有集合,查询不会抛出异常但是没有被执行?(只需1毫秒)

toArray()在预期行为中附加结果:

await collection.aggregate(aggregationSteps, {'allowDiskUse': true}).toArray();

为什么mongodb只在调用时创建结果集合.toArray(),文档在哪里这样说?我怎样才能解决这个问题?

该文档似乎没有提供任何有关此信息:

Vin*_*ren 11

MongoDB承认这种行为,但他们也说这是按设计工作的.

它已被记录为MongoDB JIRA中的错误,$ out聚合阶段不生效,并且响应表明它不是错误:

这种行为是有意的,并且在一段时间内没有使用节点驱动程序进行更改.当您通过调用Collection.prototype.aggregate"运行"聚合时,我们创建一个中间Cursor,直到请求某种I/O才会执行.这允许我们提供可链接的游标API(例如cursor.limit(..).sort(..).project(..)),在执行初始查询之前在构建器中构建查找或聚合选项.

...链接到阵列以执行出局阶段感觉不太对劲.有没有更自然的东西我没有注意到?

不幸的是,那里的链式方法只是继续构建你的聚合.以下任何方法都将导致运行初始聚合:toArray,each,forEach,hasNext,next.我们曾考虑过为像改变流这样的东西添加像exec/run这样的东西,但它仍然存在于我们的积压中.现在你理论上可以调用hasNext来运行第一个聚合并检索第一个批处理(这很可能是exec/run在内部执行的操作).

因此,看起来你必须调用其中一个方法来开始迭代光标,然后$out再执行任何操作..toArray()正如您所做的那样,添加可能是最安全的.请注意,to.Array()不会像往常一样将整个结果加载到RAM中; 因为它包含a $out,聚合返回一个空光标.

  • @Christallkeks:谢天谢地,如果你在管道中有$ out,它只会[返回一个空光标](https://docs.mongodb.com/manual/reference/method/db.collection.aggregate).将整个结果加载到内存中没有危险. (2认同)