我有大约1M文档的集合。每个文档都有internalNumber
属性,我需要在node.js代码中获取所有internalNumber
。
以前我在使用
db.docs.distinct("internalNumber")
或
collection.distinct('internalNumber', {}, {},(err, result) => { /* ... */ })
在Node。
但随着收藏的增长,我开始收到错误:distinct is too big, 16m cap
。
现在我想使用聚合。它消耗大量内存并且速度很慢,但是没关系,因为我只需要在脚本启动时执行一次。我在Robo 3T GUI工具中尝试过:
db.docs.aggregate([{$group: {_id: '$internalNumber'} }]);
它有效,我想在node.js代码中使用它,方法如下:
collection.aggregate([{$group: {_id: '$internalNumber'} }],
(err, docs) => { /* ... * });
但在Node I中出现错误:"MongoError: aggregation result exceeds maximum document size (16MB) at Function.MongoError.create"
。
请帮助克服这个限制。
答案 0 :(得分:3)
问题是本机驱动程序与默认情况下shell方法的工作方式不同,因为“shell”实际上返回了一个“游标”对象,本机驱动程序“明确地”需要此选项。
如果没有“游标”,.aggregate()
会将单个BSON文档作为文档数组返回,因此我们将其转换为游标以避免限制:
let cursor = collection.aggregate(
[{ "$group": { "_id": "$internalNumber" } }],
{ "cursor": { "batchSize": 500 } }
);
cursor.toArray((err,docs) => {
// work with resuls
});
然后,您可以使用常规方法(如.toArray()
)将结果设置为“客户端”不具有相同限制的JavaScript数组,或其他用于迭代"cursor"的方法。
答案 1 :(得分:0)
对于Casbah用户:
val pipeline = ...
collection.aggregate(pipeline, AggregationOptions(batchSize = 500, outputMode = AggregationOptions.CURSOR)