如何在MongoDB Aggregation中展开多个数组

时间:2016-12-02 12:43:02

标签: mongodb mongodb-query aggregation-framework

这就是我的文件的样子

{
    "_id" : ObjectId("584149cafda90a8b18cdfcc1"),
    "uid" : "583eaa7df4def0ec5a520d19",
    "surid" : "58414631ec5ed099538929b8",
    "createdat" : ISODate("2016-12-02T10:15:38.382Z"),
    "response" : [ 
        {
            "qid" : "649975800",
            "que" : "Which is your favourite color ?",
            "ans" : [ 
                "red", 
                "yellow"
            ]
        }, 
        {
            "qid" : "309541969",
            "que" : "which is your favourite fruits ? ",
            "ans" : [ 
                "apple", 
                "orange"
            ]
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("58414a28fda90a8b18cdfcc7"),
    "uid" : "57ff2141b893ba1a2e89ef57",
    "surid" : "58414631ec5ed099538929b8",
    "createdat" : ISODate("2016-12-02T10:17:12.800Z"),
    "response" : [ 
        {
            "qid" : "649975800",
            "que" : "Which is your favourite color ?",
            "ans" : "red"
        }, 
        {
            "qid" : "309541969",
            "que" : "which is your favourite fruits ? ",
            "ans" : "banana"
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("58414a52fda90a8b18cdfcd1"),
    "uid" : "57b300678c9f14d7555b668e",
    "surid" : "58414631ec5ed099538929b8",
    "createdat" : ISODate("2016-12-02T10:17:54.869Z"),
    "response" : [ 
        {
            "qid" : "649975800",
            "que" : "Which is your favourite color ?",
            "ans" : "red"
        }, 
        {
            "qid" : "309541969",
            "que" : "which is your favourite fruits ? ",
            "ans" : "banana"
        }
    ]
}

这就是我需要的:

{
     "que" : "Which is your favourite color ?",
     "ans" :{red:3, yellow:1}
},
{
     "que" : "which is your favourite fruits ? ",
      "ans":{apple:1, orange:1, banana:3}
}

我希望使用mongodb聚合使用独特的surid和单独的答案来获得此结果。 它完全取决于用户数据的反馈结果。

1 个答案:

答案 0 :(得分:3)

因为您事先不知道嵌入式ans数组的值,所以建议的所需输出将不可行,因为它假设您知道这些值。一种更好,更快的方法是将输出作为嵌入式计数文档,如:

{
    "ques": "Which is your favourite color ?",
    "counts": [
        { "value": "red", "count": 3 },
        { "value": "yellow", "count": 1 }
    ]
},
{
    "ques": "which is your favourite fruits ?",
    "counts": [
        { "value": "apple", "count": 1 },
        { "value": "orange", "count": 1 },
        { "value": "banana", "count": 3 }
    ]
}

可以通过运行此聚合操作来实现:

db.collection.aggregate([
    { "$unwind": "$response" },
    { "$unwind": "$response.ans" },
    {
        "$group": {
            "_id": {
                "surid": "$surid",
                "ans": "$response.ans"
            },
            "ques": { "$first": "$reponse.que" },
            "count": { "$sum": 1 }
        }
    },
    {
        "$group": {
            "_id": "$_id.surid",
            "ques": { "$first": "$ques" },
            "counts": { 
                "$push": {
                    "value": "$_id.ans",
                    "count": "$count"
                }
            }
        }
    }
])

但是,如果值是静态的并且事先已知,那么请利用 $cond 阶段中的 $group 运算符来评估基于"response.ans"字段的计数,如下所示:

db.collection.aggregate([
    { "$unwind": "$response" },
    { "$unwind": "$response.ans" },
    {
        "$group": {
            "_id": "$surid",
            "ques": { "$first": "$reponse.que" },
            "red": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$response.ans", "red" ] }, 1, 0 ]
                }
            },
            "yellow": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$response.ans", "yellow" ] }, 1, 0 ]
                }
            },
            "apple": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$response.ans", "apple" ] }, 1, 0 ]
                }
            },
            "orange": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$response.ans", "orange" ] }, 1, 0 ]
                }
            },
            "banana": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$response.ans", "banana" ] }, 1, 0 ]
                }
            }           
        }
    }
])