mongodb - 如何在 mongodb 中按多列和多个值进行分组

标签 mongodb aggregation-framework

Mongodb 集合 -

[
{ name: 'name 1', call: 'Success Call' },
{ name: 'name 1', call: 'Repeat Call' },
{ name: 'name 3', call: 'Repeat Call' },
{ name: 'name 3', call: 'Unsuccess Call' }
{ name: 'name 2', call: 'Success Call' },
{ name: 'name 2', call: 'Repeat Call' }
{ name: 'name 2', call: 'Repeat Call' }
{ name: 'name 2', call: 'Unsuccess Call' }
.
.
.
.
]

我点击了这个链接 group and sum multiple columns using aggregation framework并结束了这个输出。

[
{
    "_id": 1,
    "Calls": [
        {
            "call": "Repeat Call",
            "callCount": 2
        },
        {
            "call": "Unsuccess Call",
            "callCount": 1
        },
        {
            "call": "Success Call",
            "callCount": 1
        }
    ],
    "Names": [
        {
            "name": {
                "name": "name 4"
            },
            "nameCount": 1
        },
        {
            "name": {
                "name": "name 3"
            },
            "nameCount": 1
        },
        {
            "name": {
                "name": "name 1"
            },
            "nameCount": 2
        }
    ]
}
]

而我实际上需要这样的东西

[
{
    "name": "name 4",
    "nameCount": 1,
    "Success Call":1,
    "Unsuccess Call":0,
    "Repeat Call":0
},
{
    "name": "name 3",
    "nameCount": 1,
    "Success Call":2,
    "Unsuccess Call":3,
    "Repeat Call":1
},
{
    "name": "name 1",
    "nameCount": 2,
    "Success Call":1,
    "Unsuccess Call":1,
    "Repeat Call":1
}
]

谁能帮我解决这个问题? 提前致谢!

最佳答案

在聚合管道中,对于 MongoDB 版本 3.6 和更新版本,您可以利用 $arrayToObject 运算符和一个 $replaceRoot 管道以获得所需的 JSON 输出。这适用于调用字段的未知值。

您需要运行以下聚合管道:

db.collection.aggregate([
    { "$group": {
        "_id": { 
            "name": "$name",
            "call": "$call"
        },
        "count": { "$sum": 1 }
    } },
    { "$group": {
        "_id": "$_id.name",
        "counts": {
            "$push": {
                "k": "$_id.call",
                "v": "$count"
            }
        },
        "nameCount": { "$sum": 1 }
    } },
    { "$replaceRoot": { 
        "newRoot": { 
            "$mergeObjects": [ 
                { "$arrayToObject": "$counts" }, 
                "$$ROOT" 
             ] 
        } 
    } },
    { "$project": { "counts": 0 } }
])

对于不支持上述运算符的早期 MongoDB 版本,请利用 $cond $group 中的运算符阶段根据已知的 call 值评估计数,如下所示:

db.collection.aggregate([
    { "$group": {
        "_id": "$name",
        "nameCount": { "$sum": 1 },
        "Success Call": {
            "$sum": {
                "$cond": [ { "$eq": [ "$call",  "Success Call" ] }, 1, 0]
            }
        },
        "Repeat Call": {
            "$sum": {
                "$cond": [ { "$eq": [ "$call",  "Repeat Call" ] }, 1, 0]
            }
        },
        "Unsuccess Call": {
            "$sum": {
                "$cond": [ { "$eq": [ "$call",  "Unsuccess Call" ] }, 1, 0]
            }
        }
    } },
    { "$project": {
        "_id": 0, 
        "name": "$_id",
        "nameCount": 1,
        "Success Call":1,
        "Unsuccess Call":1,
        "Repeat Call":1               
    } }
])

关于mongodb - 如何在 mongodb 中按多列和多个值进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026941/

相关文章:

MongoDB按ObjectIds数组聚合匹配

MongoDB 聚合框架 日期现在

javascript - 使用 MongoDB 连接池的 NodeJS 一次性脚本 - 如何终止?

c# - 使用 Update.Push 时,mongodb C# 驱动程序未在嵌入式对象列表中生成新添加文档的 ObjectId

angularjs - angular-meteor 根据参数查找 MongoDb 集合并返回

Laravel Mongo 多对多关系不起作用

MongoDB 查询 - 返回切片数组

javascript - 在 JavaScript 中将 ObjectID (Mongodb) 转换为字符串

javascript - 类型错误 : Object #<MongoClient> has no method 'db'

node.js - mongoDB 聚合的分页 [Node.js]