Mongo聚合管道,找出每个用户的数组中的条目总数

时间:2018-02-12 14:21:44

标签: mongodb aggregation

我有一个集合,我们称之为“用户”。在这个集合中有一个属性条目,它包含一个可变大小的字符串数组

我想知道我的收藏中这些字符串的总数。

db.users.find()
> [{ entries: [] }, { entries: ['entry1','entry2']}, {entries: ['entry1']}]

到目前为止,我已经做了很多尝试,这是我最接近的一些。

     db.users.aggregate([
      { $project:
        { numberOfEntries:
          { $size: "$entries" } }
          },
           { $group: 
             {_id: { total_entries: { $sum: "$entries"}
                     }
                  } 
               }
            ])

这给了我一个包含总条目数的用户列表,现在我想要的是每个total_entries数字加起来得到我的总数。我做错了什么想法。或者,如果有更好的方法来启动它?

3 个答案:

答案 0 :(得分:1)

如果你想要整个不同的条目:

> db.users.aggregate([
   { $unwind: "$entries" },
   { $group: { _id: "$entries" } },
   { $count: "total" }
])
{ "total" : 2 }

如果你想要整个nbr条目:

> db.users.aggregate( [ { $unwind: "$entries" }, { $count: "total" } ] )
{ "total" : 3 }

这使用了“展开”运算符,该运算符从记录中展平数组的元素:

> db.users.aggregate( [ { $unwind: "$entries" } ] )
{ "_id" : ObjectId("5a81a7a1318e1cfc10250430"), "entries" : "entry1" }
{ "_id" : ObjectId("5a81a7a1318e1cfc10250430"), "entries" : "entry2" }
{ "_id" : ObjectId("5a81a7a1318e1cfc10250431"), "entries" : "entry1" }

答案 1 :(得分:1)

可能的解决方案可能是:

db.users.aggregate([{
    $group: {
        _id: 'some text here',
        count: {$sum: {$size: '$entries'}}
    }
}]);

这将为您提供所有用户的所有条目的总计数,看起来像

[
    {
        _id: 'some text here',
        count: 3
    }
]

如果您想要个人输入计数,我会使用$ unwind。 那看起来像是

db.users.aggregate([
    { $unwind: '$entries' },
    {$group: {
        _id: '$entries',
        count: {$sum: 1}
    }
])

这将为您提供以下内容:

[
    {
        _id: 'entry1',
        count: 2
    },
    {
        _id: 'entry2',
        count: 1
    }
]

答案 2 :(得分:1)

虽然您只需要在 $group 阶段指定_id null值,然后计算所有输入文档的累计值,但您的方向正确整个即

db.users.aggregate([
    {
        "$project": {
            "numberOfEntries": { 
                "$size": {
                    "$ifNull": ["$entries", []]
                }
            }          
        }
    },
    {
        "$group": {
            "_id": null, /*  _id of null to get the accumulated values for all the docs */
            "totalEntries": { "$sum": "$numberOfEntries" }
        }       
    }
])

或者只使用一个管道:

db.users.aggregate([
    {
        "$group": {
            "_id": null, /*  _id of null to get the accumulated values for all the docs */
            "totalEntries": { 
                "$sum": { 
                    "$size": {
                        "$ifNull": ["$entries", []]
                    }
                }   
            }
        }       
    }
])