【问题标题】:Aggregate pipeline Match -> Lookup -> Unwind -> Match issue聚合管道匹配 -> 查找 -> 展开 -> 匹配问题
【发布时间】:2018-01-21 23:32:07
【问题描述】:

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

运行此查询:

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),事情就不会像我预期的那样工作。

最终的管道是:

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。我尝试了我能想到的一切,但无法让它发挥作用,也无法理解为什么它不起作用。

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    我能够让它与以下管道一起工作:

    {
        $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 这不能用作 LHS $match,因此需要添加一个额外的辅助属性。

    【讨论】:

      猜你喜欢
      • 2023-02-25
      • 2020-06-13
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 2021-06-27
      相关资源
      最近更新 更多