避免总计16MB的限制

我有一个约1M文件的集合。 每个文档都有internalNumber属性,我需要在我的node.js代码中获得所有的internalNumber

以前我在用

 db.docs.distinct("internalNumber") 

要么

 collection.distinct('internalNumber', {}, {},(err, result) => { /* ... */ }) 

在节点。

但随着collections的增长,我开始得到这样的错误: distinct is too big, 16m cap

现在我想要使用聚合。 它消耗了大量的内存,而且速度很慢,但是这样可以,因为我只需要在脚本启动时只执行一次。 我已经尝试过Robo 3T GUI工具:

 db.docs.aggregate([{$group: {_id: '$internalNumber'} }]); 

它的工作原理,我想在node.js中使用它的代码如下:

 collection.aggregate([{$group: {_id: '$internalNumber'} }], (err, docs) => { /* ... * }); 

但在节点中,我得到一个错误: "MongoError: aggregation result exceeds maximum document size (16MB) at Function.MongoError.create"

请帮助克服这个限制。

问题在于,本地驱动程序与shell方法在缺省情况下的工作方式不同,因为“shell”实际上是返回一个“游标”对象,本地驱动程序需要“明确”使用此选项。

如果没有“游标”, .aggregate()返回一个单一的BSON文档作为文档数组,所以我们把它转换成一个游标来避免这个限制:

 let cursor = collection.aggregate( [{ "$group": { "_id": "$internalNumber" } }], { "cursor": { "batchSize": 500 } } ); cursor.toArray((err,docs) => { // work with resuls }); 

然后,您可以使用像.toArray()这样的常规方法将结果生成为“客户端”上不具有相同限制的JavaScript数组,或用于迭代“游标”的其他方法。

对于Casbah用户:

 val pipeline = ... collection.aggregate(pipeline, AggregationOptions(batchSize = 500, outputMode = AggregationOptions.CURSOR)