【问题标题】:Mongodb : count array values with mapreduce / aggregationMongodb:使用mapreduce /聚合计算数组值
【发布时间】:2012-12-28 06:23:32
【问题描述】:

我有以下结构的文档:

{
    "name" : "John",
    "items" : [
       {"key1" : "value1"},
       {"key1" : "value1"}
    ]
}

并构建了一个简单的函数来计算“项目”总数。

var count = 0;
db.collection.find({},{items:1}).limit(10000).forEach(
    function (doc) {
        if(doc.items){
               count += doc.items.length;
        }
    }
)
print(count);

但是在大​​约 100 万个项目之后,我的函数中断了,Mongo 退出了。我已经查看了新的聚合框架以及 mapreduce 函数,但我不确定哪个最适合用于这样的简单计数。

欢迎提出建议!谢谢。

【问题讨论】:

  • 你正在得到一个游标超时prolly,如果你要运行说10K,就像你在循环中显示的那样,它应该每次打开一个新游标,所以你不应该遭受超时问题。

标签: mongodb mapreduce aggregation-framework mongo-shell


【解决方案1】:

当你使用聚合http://docs.mongodb.org/manual/core/aggregation-pipeline/时变得非常容易

db.collection.aggregate(
     { $unwind : "$items" }, 
     { $group  : {_id:null, items_count : {$sum:1} }}
)

返回每个文档的项目数,

{ $group  : {_id:"$_id", items_count : {$sum:1} }}

【讨论】:

    【解决方案2】:

    您可以将 doc.items 的长度存储为 doc 的元素。这种方法会导致磁盘冗余,但却是处理大型集合的一种快速简便的方法。

    {
        "name" : "John",
        "itemsLength" : 2,
        "items" : [
           {"key1" : "value1"},
           {"key1" : "value1"}
        ]
    }
    

    另一种选择可能是使用 mapreduce,但我认为,不分片 mapreduce 会很慢。

    【讨论】:

    • 现在正在统计“items”的长度,但我还需要统计那些之前没有的文档。
    • 您可以一次更新以前的文档,以便所有文档都具有 itemLength 属性。当所有文档都有itemLength时,可以用$sum聚合。
    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 2016-03-08
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 2016-12-21
    相关资源
    最近更新 更多