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

时间:2016-05-04 11:48:59

标签: mongodb aggregation-framework

Mongodb Collection -

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

任何人都可以帮我整理一下吗? 提前致谢!

1 个答案:

答案 0 :(得分:5)

在聚合管道中,对于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               
    } }
])