Javascript 有条件地处理mongodb组中的项(聚合管道)

Javascript 有条件地处理mongodb组中的项(聚合管道),javascript,mongodb,aggregation-framework,Javascript,Mongodb,Aggregation Framework,考虑一个具有调查结果的MongoDB集合,其中结果可以是反馈类型(任意数量的自由文本答案)或多个(用户可以选择全部、无或部分提供的答案)。所有问题都有一个唯一的名称,并且该名称的类型和答案集保持一致 考虑这组示例条目: { "_id" : ObjectId("572c4af25e30ae25a0307df0"), "question" : "Q1", "type" : "feedback", "answers" : [ "feedback

考虑一个具有调查结果的MongoDB集合,其中结果可以是反馈类型(任意数量的自由文本答案)或多个(用户可以选择全部、无或部分提供的答案)。所有问题都有一个唯一的名称,并且该名称的类型和答案集保持一致

考虑这组示例条目:

{ 
    "_id" : ObjectId("572c4af25e30ae25a0307df0"), 
    "question" : "Q1", 
    "type" : "feedback", 
    "answers" : [
        "feedback value 1", 
        "feedback value 2"
    ]
}
{ 
    "_id" : ObjectId("572c4b7a5e30ae25a0307dfa"), 
    "question" : "Q1", 
    "type" : "feedback", 
    "answers" : [
        "feedback value 2"
    ]
}
{ 
    "_id" : ObjectId("572c4b885e30ae25a0307dfc"), 
    "question" : "Q2", 
    "type" : "feedback", 
    "answers" : [
        "feedback value 1"
    ]
}
{ 
    "_id" : ObjectId("572c4ba65e30ae25a0307dfe"), 
    "question" : "Q3", 
    "type" : "multi", 
    "answers" : [
        {
            "value" : "A1", 
            "chosen" : true
        }, 
        {
            "value" : "A2", 
            "chosen" : false
        }
    ]
}
{ 
    "_id" : ObjectId("572c4c125e30ae25a0307e00"), 
    "question" : "Q3", 
    "type" : "multi", 
    "answers" : [
        {
            "value" : "A1", 
            "chosen" : false
        }, 
        {
            "value" : "A2", 
            "chosen" : false
        }
    ]
}
我想要的是创建某种评估聚合,其中结果应该如下所示(每个答案对应一个结果文档):

那么,我如何创建这样一个聚合呢?我首先想到了MapReduce,但正如大家都说应该更喜欢聚合管道一样,我尝试了一下

我的第一步是按问题id(“问题”字段)分组。然后,我想在小组阶段添加与反馈和多重调查的答案类型相对应的其他字段。然后,另一个“投影”阶段应为输出选择适当的字段

db.survey.aggregate(
    [
        // Stage 1
        {
            $group: {
                _id: "$question",
                type: {
                    $first: "$type"
                },
                answersFeedback: {
                    // this creates nested arrays 
                    // instead of an array of strings
                    $addToSet: {
                        $cond: [{
                            $eq: ["$type", "feedback"]
                        }, "$answers", []]
                    }
                },
                // no idea how to achieve this
                answersMulti: {
                    $first: {
                        $literal: {
                            "foo": 42
                        }
                    }
                }
            }
        },

        // Stage 2
        {
            $project: {
                "type": 1,
                // select answer field according to type
                "answers": {
                    $cond: [{
                        $eq: ["$type", "multi"]
                    }, "$answersMulti", "$answersFeedback"]
                }
            }
        }

    ]
);
不幸的是,反馈答案会导致嵌套数组

{ 
    "_id" : "Q2", 
    "type" : "feedback", 
    "answers" : [
        [
            "feedback value 1"
        ]
    ]
}
我不知道如何处理多重投票。你能帮我继续吗


数据库运行在v3.2.4服务器上。所使用的模式(数据格式)是实际数据的简化版本,我可能不会修改它,我确实需要按原样进行处理。

请快速思考,如果您不想要嵌套结果,是否尝试过使用“展开”命令拆分答案array@iestync是的,谢谢,我还没想到。它解决了我的反馈问题,但我仍然不知道如何重新调整多部分的大小。很抱歉,我错过了这一部分,也许如果您在管道的早期解开答案数组,那么您可以使用project来收集值,这些值可预测吗?e、 g.总是A1、A2I我认为您应该运行两个不同的查询,并在客户端合并结果。我还看到
如果type==“multi”
您希望使用数据作为键,这在聚合框架中是不可能的,除非您知道所有可能的值,即
A1、A2
{ 
    "_id" : "Q2", 
    "type" : "feedback", 
    "answers" : [
        [
            "feedback value 1"
        ]
    ]
}