我有一个大型mongodb集合:
第1部分:不同值
我需要找到field1的所有不同值。
调用db.myCollection.distinct("field1")失败,因为结果集中有超过16 in的数据。
因为shard键是一个索引,这应该是一个覆盖的查询。
第2部分:返回排序结果
假设上面有一个答案,我想从失败中恢复,也就是,按顺序返回结果。这并不重要。
排序输出的目标:如果查询在中途失败,我可以通过添加field1:{$gt:lastGoodValue}的查询说明符,从停止的地方恢复。
那么:这有可能吗?容易吗?我必须聚合还是映射减少?目前,我正在迭代所有3亿条记录,它不必要地推送了大量数据。
发布于 2016-09-29 22:08:50
集合不同的命令(doc链接)返回一个变量,一个数组。此变量作为BSON文档发送,其中MongoDB中的最大大小限制为16 max。
在数组中设置结果集对于某些情况是方便的,但是如果它不一定适合16 as,那么您将无法像您所发现的那样使用它。
第一部分:答案
相反,您可以在聚合命令中使用检索不同的值阶段的$group。您也可以使用MapReduce,但是聚合具有更好的性能,因此我将重点讨论这一点。
db.myCollectoin.aggregate( [ { $group : { _id : "$myField" } } ] )
这将将结果从单个数组变量更改为游标,与常规查询/查找命令相同。因此,迭代不同的值客户端的方式是不同的,但是您可以继续获取越来越多的值,直到游标完成为止。
使用相同的命令,无论您有集群、副本集,还是独立的单神。一个重要的性能考虑是是否对被明确分组的字段进行了索引,但是正如您提到的,这个字段是一个切分键中的主导字段,我们知道它是。
第二部分:答案
是的,你可以把它分类。在$sort后添加一个$group阶段。
db.myCollection.aggregate( [
{ $group : { _id : "$myField" } },
{ $sort: { "_id": 1 } }
] )
如果您必须从某个点重新启动查询,您将添加一个$match阶段作为聚合管道中的第一个操作。例如{ $match: {"myField": { "$gt": "AbCdEf...."} } },
的新用户注意:在$sort阶段的第二个"_id“是$group阶段的"_id”字段输出,即不同的"myField“值。它不是由基础集合中的"_id“值来分类的。
如果您愿意的话,使用$project阶段可以重命名中间阶段的"_id“键名。
db.myCollection.aggregate( [
{ $group : { _id : "$myField" } },
{ $project : {
"_id" : false, /*stop it appearing as "_id" */
"myField" : "$_id" /*put original field name "myField" back on*/
} },
{ $sort: { "myField": 1 } }
] )
https://stackoverflow.com/questions/39777491
复制相似问题