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

Mongo aggregation pipeline, finding out the total number of entries in an array per user

我有一个 collection,我们称它为 'user'。在这个 collection 中有一个 属性 条目,其中包含一个可变大小的字符串数组,

我想找出我 collection 中这些字符串的总数。

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

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

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

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

如果您想要条目的整体不同编号:

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

如果您想要条目的整体编号:

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

这利用 "unwind" 运算符从记录中压平数组元素:

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

可能的解决方案是:

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
    }
]

您的方向是正确的,尽管您只需要在 $group 阶段指定一个 _id 空值来计算所有的累加值输入文档作为一个整体,即

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", []]
                    }
                }   
            }
        }       
    }
])