简体   繁体   English

Mongodb 聚合 $unwind 然后计数

[英]Mongodb aggregation $unwind then count

Here is my problem : in my Mongo database, I have a collection with items like :这是我的问题:在我的 Mongo 数据库中,我有一个包含以下项目的集合:

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

I would like to get the total number of steps 'start'.我想获得“开始”的总步数。 I tryed to use the MongoDB aggregation framework : I use $unwind on steps.action and $match on steps.action to match 'start'.我尝试使用 MongoDB 聚合框架:我在steps.action上使用$unwind并在steps.action上使用$match来匹配“开始”。

However, I get too much data and reach the aggregation's limit : exception: aggregation result exceeds maximum document size (16MB) .但是,我获得了太多数据并达到了聚合的限制: exception: aggregation result exceeds maximum document size (16MB) I don't need the data, I just want the count, but I couldn't find how to do it (tryed with $group without success).我不需要数据,我只想要计数,但我找不到怎么做(用 $group 尝试但没有成功)。

Thanks in advance,提前致谢,

If you want the count you can use this如果你想要计数,你可以使用这个

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

but this will not take into account if steps contain multiple steps with action start .但这不会考虑如果步骤包含多个带有 action start步骤。

When you also need to count all steps with start then you need to unwind the array, make a match on steps.action and then group the results to count.当您还需要使用start计算所有步骤时,您需要展开数组,对 steps.action 进行匹配,然后将结果分组以进行计数。

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

try this尝试这个

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

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

You may not need aggregation for this simple query.对于这个简单的查询,您可能不需要聚合。 See below code.见下面的代码。

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);
};

This code creates random number of actions.此代码创建随机数量的操作。 If you need only number of documents which contains action: 'start' then below query.如果您只需要包含 action: 'start' 的文档数量,则在查询下方。

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

I get following count in my run.我在跑步中得到了以下计数。

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

But if you need number of {action: 'start'} in the documents then aggregation query needed.但是,如果您需要文档中的 {action: 'start'} 数量,则需要聚合查询。 You unwind then match你放松然后匹配

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

This outputs:这输出:

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



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

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

)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM