Mongodb聚合$ unwind然后计数

时间:2014-12-05 10:34:53

标签: mongodb aggregation-framework

这是我的问题:在我的Mongo数据库中,我有一个包含以下项目的集合:

{
  'id': 1,
  'steps': [
    {
      action: 'start',
      info: 'foo'
    },
    {
      action: 'stop',
      info: 'bar'
    }
  ]
}

我想获得步骤的总数'开始'。 我尝试使用MongoDB聚合框架:我使用$unwind上的steps.action$match上的steps.action来匹配“开始”#。

但是,我收到太多数据并达到了聚合的限制: exception: aggregation result exceeds maximum document size (16MB)。我不需要数据,我只是想要数,但我无法找到如何做到这一点(尝试使用$ group但没有成功)。

提前致谢,

4 个答案:

答案 0 :(得分:10)

如果你想要计数,你可以使用这个

db.test.count({"steps.action":"start"})

但如果步骤包含多个带有操作start的步骤,则不会考虑这一点。

当您还需要使用start计算所有步骤时,您需要展开数组,在steps.action上进行匹配,然后将结果分组以进行计数。

db.test.aggregate({$unwind:"$steps"}, {$match:{"steps.action":"start"}},{ $group: { _id: null, count: { $sum: 1 } } })

答案 1 :(得分:4)

试试这个

db.collection.aggregate(
   { $unwind : "$steps" },
   {$match:{'steps.action':'start'}},
   {$group:{_id:null,count:{$sum:1}}}
).pretty()

答案 2 :(得分:0)

在mongodb聚合框架中,管道阶段最大限制为100MB大小,而它提供的结果是BSON文件或集合文档,最大大小为16MB 所以你可以$match只需要条件和$group它,这样只输出小于16MB的所需结果。

答案 3 :(得分:-3)

您可能不需要对此简单查询进行聚合。见下面的代码。

for (var i = 10000; i >= 0; i--) {
    var a = {
      'id': 1,
      'steps': [
        {
          action: 'start',
          info: 'foo'
        },
        {
          action: 'stop',
          info: 'bar'
        }
      ]
    }

    a.id = i;
    var rnd = Math.floor((Math.random() * 3) + 1);
    if (rnd == 1)
    {
        a.steps[0].action = 'none';
    }
    if (rnd == 2)
    {
        a.steps.push({ action: 'start', info: 'foo' })

    }
    db.obj.insert(a);
};

此代码创建随机数量的操作。 如果您只需要包含操作的文档数量:' start'然后在查询下方。

db.obj.count({"steps.action":"start"})

我在跑步中得到了计数。

> db.obj.count({"steps.action":"start"})
6756

但是如果您需要在文档中使用{action:' start'},则需要进行聚合查询。 你放松然后匹配

db.obj.aggregate(
[
{ $unwind : "$steps"},
{$match: { "steps.action" : "start" }},
{
$group:
 {
   _id:  null
   ,count: { $sum: 1 }
 }
}
]
)

输出:

{ "_id" : null, "count" : 10054 }



if you get your exception again use **allowDiskUse : true** option. See [here][1].

db.obj.aggregate(
[
 ....
]
 ,
 { 
   allowDiskUse : true
 }

)
相关问题