聚合管道匹配 - >查找 - >放松 - >匹配问题

时间:2017-08-14 07:15:36

标签: mongodb aggregation-framework

我很困惑为什么下面的代码不起作用。有人可以解释一下吗? 对于某些情况:我的目标是获得与调查数据库的答案选项相关联的分数,其中答案存储在与问题分开的单独集合中。问题集包含一系列答案选项,这些答案选项都有分数。

运行此查询:

db.answers.aggregate([
{
    $match: {
        userId: "abc",
        questionId: ObjectId("598be01d4efd70a81c1c5ad4")
    }
},
{
    $lookup: {
        from: "questions",
        localField: "questionId",
        foreignField: "_id",
        as: "question"
    }
},
{
    $unwind: "$question"
},
{
    $unwind: "$question.options"
},
{
    $unwind: "$answers"
}
])

我明白了:

{
    "_id" : ObjectId("598e588e0c5e24452c9ee769"),
    "userId" : "abc",
    "questionId" : ObjectId("598be01d4efd70a81c1c5ad4"),
    "answers" : {
        "id" : 20
    },
    "question" : {
        "_id" : ObjectId("598be01d4efd70a81c1c5ad4"),
        "options" : {
            "id" : 10,
            "score" : "12"
        }
    }
}
{
    "_id" : ObjectId("598e588e0c5e24452c9ee769"),
    "userId" : "abc",
    "questionId" : ObjectId("598be01d4efd70a81c1c5ad4"),
    "answers" : {
        "id" : 20
    },
    "question" : {
        "_id" : ObjectId("598be01d4efd70a81c1c5ad4"),
        "options" : {
            "id" : 20,
            "score" : "4"
        }
    }
}

一切都很好。如果我现在向原始查询添加一个匹配,该匹配应该找到与答案具有相同ID的答案选项(例如questions.options.id == answers.id),那么事情就不会像我期望的那样发挥作用。 / p>

最终的管道是:

db.answers.aggregate([
{
    $match: {
        userId: "abc",
        questionId: ObjectId("598be01d4efd70a81c1c5ad4")
    }
},
{
    $lookup: {
        from: "questions",
        localField: "questionId",
        foreignField: "_id",
        as: "question"
    }
},
{
    $unwind: "$question"
},
{
    $unwind: "$question.options"
},
{
    $unwind: "$answers"
},
{
    $match: {
        "question.options.id": "$answers.id"
    }
},
{
    $project: {
        _id: 0,
        score: "$question.options.score"
    }
}
])

返回空结果。但是,如果我将$match的RHS从"$answers.id"更改为20,则会返回预期的score: 4。我尝试了所有我能想到的东西,但无法让它发挥作用,无法理解为什么它不起作用。

1 个答案:

答案 0 :(得分:0)

我能够使用以下管道:

{
    $match: {
        userId: "abc",
        questionId: ObjectId("598be01d4efd70a81c1c5ad4")
    }
},
{
    $lookup: {
        from: "questions",
        localField: "questionId",
        foreignField: "_id",
        as: "question"
    }
},
{
    $unwind: "$question"
},
{
    $unwind: "$question.options"
},
{
    $unwind: "$answers"
},
{
    $addFields: {
        areEqual: { $eq: [ "$question.options.id", "$answers.id" ] }
    }
},
{
    $match: {
        areEqual: true
    }
},
{
    $project: {
        _id: 0,
        score: "$question.options.score"
    }
}

我认为它与直接匹配不起作用的原因是questions.options.id实际上没有引用预期的字段...我需要使用$questions.options.id这不起作用作为$match的LHS,因此需要添加额外的辅助属性。