MongoDB 在索引列上选择 count(distinct x) - 计算大型数据集的唯一结果

2023-12-29

I have gone through several articles and examples, and have yet to find an efficient way to do this SQL query in MongoDB (where there are millions of rows documents)

第一次尝试

(例如,从这个几乎重复的问题 -Mongo相当于SQL的SELECT DISTINCT? https://stackoverflow.com/questions/5236160/mongo-equivalent-of-sqls-select-distinct)

db.myCollection.distinct("myIndexedNonUniqueField").length

显然我收到了这个错误,因为我的数据集很大

Thu Aug 02 12:55:24 uncaught exception: distinct failed: {
        "errmsg" : "exception: distinct too big, 16mb cap",
        "code" : 10044,
        "ok" : 0
}

第二次尝试

我决定尝试做一个团体

db.myCollection.group({key: {myIndexedNonUniqueField: 1},
                initial: {count: 0}, 
                 reduce: function (obj, prev) { prev.count++;} } );

但我收到了这个错误消息:

exception: group() can't handle more than 20000 unique keys

第三次尝试

我还没有尝试过,但有几个建议涉及mapReduce

e.g.

  • 这个如何在mongodb中进行不同和分组? https://stackoverflow.com/questions/6222811/how-to-do-distinct-and-group-in-mongodb(不接受,答案作者/OP没有测试它)
  • 这个MongoDB 按功能分组 https://stackoverflow.com/questions/8769323/mongodb-group-by-functionalities(看起来与第二次尝试类似)
  • 这个http://blog.emmettshear.com/post/2010/02/12/Counting-Uni​​ques-With-MongoDB http://blog.emmettshear.com/post/2010/02/12/Counting-Uniques-With-MongoDB
  • 这个https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/trDn3jJjqtE https://groups.google.com/forum/?fromgroups#!topic/mongodb-user/trDn3jJjqtE
  • 这个http://cookbook.mongodb.org/patterns/unique_items_map_reduce/ http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

Also

GitHub 上似乎有一个拉取请求修复了.distinct方法提到它应该只返回一个计数,但它仍然是开放的:https://github.com/mongodb/mongo/pull/34 https://github.com/mongodb/mongo/pull/34

但此时我认为有必要在这里问一下,这个主题的最新情况是什么?我应该转向 SQL 或其他 NoSQL 数据库来获取不同计数吗?或者有什么有效的方法吗?

Update:

MongoDB 官方文档的这个评论并不令人鼓舞,这是准确的吗?

http://www.mongodb.org/display/DOCS/Aggregation#comment-430445808 http://www.mongodb.org/display/DOCS/Aggregation#comment-430445808

Update2:

似乎新的聚合框架回答了上述评论...(MongoDB 2.1/2.2 及更高版本,开发预览版可用,不适用于生产)

http://docs.mongodb.org/manual/applications/aggregation/ http://docs.mongodb.org/manual/applications/aggregation/


1)最简单的方法是通过聚合框架。这需要两个“$group”命令:第一个按不同值进行分组,第二个对所有不同值进行计数

pipeline = [ 
    { $group: { _id: "$myIndexedNonUniqueField"}  },
    { $group: { _id: 1, count: { $sum: 1 } } }
];

//
// Run the aggregation command
//
R = db.runCommand( 
    {
    "aggregate": "myCollection" , 
    "pipeline": pipeline
    }
);
printjson(R);

2)如果你想用 Map/Reduce 来做到这一点,你可以。这也是一个两阶段的过程:在第一阶段,我们构建一个新集合,其中包含键的每个不同值的列表。在第二个例子中,我们对新集合执行 count() 操作。

var SOURCE = db.myCollection;
var DEST = db.distinct
DEST.drop();


map = function() {
  emit( this.myIndexedNonUniqueField , {count: 1});
}

reduce = function(key, values) {
  var count = 0;

  values.forEach(function(v) {
    count += v['count'];        // count each distinct value for lagniappe
  });

  return {count: count};
};

//
// run map/reduce
//
res = SOURCE.mapReduce( map, reduce, 
    { out: 'distinct', 
     verbose: true
    }
    );

print( "distinct count= " + res.counts.output );
print( "distinct count=", DEST.count() );

请注意,您无法返回内联映射/归约的结果,因为这可能会超出 16MB 文档大小限制。你can将计算保存在集合中,然后 count() 集合的大小,或者您可以从 mapReduce() 的返回值中获取结果数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MongoDB 在索引列上选择 count(distinct x) - 计算大型数据集的唯一结果 的相关文章

随机推荐