【问题标题】:In MongoDB, how do I find distinct values of a large, sharded collection?在 MongoDB 中,如何找到大型分片集合的不同值?
【发布时间】:2016-09-29 18:27:14
【问题描述】:

我有一个很大的 mongodb 集合:

  • 带有 3 个分片,
  • 总计 3 亿条记录(至少)
  • 分片键为 (field1:1,field2:1)
  • 还有其他非索引字段。
  • Field1 是一个约 200 个字符的字符串
  • Field2 是一个整数。
  • Field1 有大约 1000 万个不同的值,并且一直在增加。

第 1 部分:不同的值

我需要找到 field1 的所有不同值。

调用 db.myCollection.distinct("field1") 失败,因为结果集中有超过 16MB 的数据。

由于分片键是一个索引,这应该是一个覆盖查询。

第 2 部分:返回排序结果

假设上述问题有答案,我想让它从失败中恢复,即按排序顺序返回结果。这并不重要。

排序输出的目标:如果查询中途失败,我可以通过添加 field1:{$gt:lastGoodValue} 的查询说明符从上次中断的地方继续。

那么:这可能吗?简单的?我必须聚合或映射减少吗?目前,我正在遍历所有 300M 记录,它会不必要地推送大量数据。

【问题讨论】:

    标签: python mongodb-query


    【解决方案1】:

    collection distinct 命令 (doc link) 返回一个变量,一个数组。此变量作为 BSON 文档发送,在 MongoDB 中最大大小限制为 16MB。

    在某些情况下,将结果集保存在数组中很方便,但如果不确定它是否适合 16MB,那么您将无法使用它,正如您所发现的那样。

    第 1 部分答案

    相反,您可以 retrieve distinct values 在聚合命令中使用 $group 阶段。您也可以使用 MapReduce,但聚合具有更好的性能,因此我将重点介绍这一点。

    db.myCollectoin.aggregate( [ { $group : { _id : "$myField" } } ] )
    

    这会将结果从单个数组变量更改为游标,与普通查询/查找命令相同。因此,您在客户端迭代不同值的方式会有所不同,但您可以继续获取越来越多的值,直到游标完成。

    无论您有集群、副本集还是独立的 mongod,都使用相同的命令。一个重要的性能考虑因素是明确分组的字段是否被索引,但正如您提到的,该字段是分片键中的前导字段,我们知道它是。

    第 2 部分答案

    是的,您可以对其进行排序。在 $group 之后添加 $sort 阶段。

    db.myCollection.aggregate( [ 
      { $group : { _id : "$myField" } }, 
      { $sort: { "_id": 1 } } 
    ] )
    

    如果您必须从某个点再次重新启动查询,您可以添加 $match stage 作为聚合管道中的第一个操作。例如。 { $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 } } 
    ] )
    

    【讨论】:

    • 谢谢!我查看了所有 MongoDB 文档,但没有详细说明。我建议有人将“常见查询”放在一起,因为它必须在上面,我需要为几个集合做很长时间,最后才开始在这里提问。太好了!
    猜你喜欢
    • 2021-07-14
    • 2016-04-28
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2014-04-13
    • 2013-08-31
    • 2018-12-15
    相关资源
    最近更新 更多