MongoDB 中的子查询 return 具有特定字段的单个元素

Sub-query in MongoDB for return a single element with a specific field

我有两个集合,其中一个有一个包含另一个 ID 的数组。我需要 return 第一个集合中的一个元素和第二个集合中的一个元素,但只需要具有特定字段的元素。我会解释清楚的。

我试着用它做点什么,但不太明白操作。 https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

我的问题:

{
  "solved": false,
  "answer": [
     "5d969dbf7d496a256443eeca",
     "5d969f7b7d496a256443eecb"
  ],
  "_id": "5d93dfaf40024619dcc61896",
  "user": "5d8963afa0014a289c8d7112",
  "title": "Ola mundo",
  "description": "esse e um teste",
  "discipline": "5d8fb8e04becf712f8293b5b",
  "createdAt": "2019-10-01T23:22:23.168Z",
  "__v": 0
},

我的遮阳篷

{
  "official": false,
  "_id": "5d969dbf7d496a256443eeca",
  "description": "Toma aqui a sua resposta",
  "createdAt": "2019-10-04T01:17:51.454Z",
  "__v": 0
},
{
  "official": true,
  "_id": "5d969f7b7d496a256443eecb",
  "description": "Esste e um teeeeste",
  "createdAt": "2019-10-04T01:25:15.829Z",
  "__v": 0
}

我需要 return 问题模型,以及 "official" 字段等于 "true" 的 Awnser 模型。我是 mongoDB 的新手,所以我正在寻求帮助。 我认为 sql.

中可能有类似子查询的东西

最简单的方法是使用聚合。

您需要使用 $lookup 将 answer 数组中的所有 id 连接到 Answer 集合中,然后使用 $filter 按 "official".

过滤它

如果 _id 匹配,则加入 Answer 集合中的文档

{
    $lookup: {
        from: "Answer",
        foreignField: "_id",
        localField: "answer",
        as: "answer"
    }

}

结果将是:

{
    "_id" : ObjectId("5d93dfaf40024619dcc61896"),
    "solved" : false,
    "answer" : [
        {
            "_id" : ObjectId("5d969dbf7d496a256443eeca"),
            "official" : false,
            "description" : "Toma aqui a sua resposta",
            "createdAt" : "2019-10-04T01:17:51.454Z",
            "__v" : 0
        },
        {
            "_id" : ObjectId("5d969f7b7d496a256443eecb"),
            "official" : true,
            "description" : "Esste e um teeeeste",
            "createdAt" : "2019-10-04T01:25:15.829Z",
            "__v" : 0
        }
    ],
    "user" : "5d8963afa0014a289c8d7112",
    "title" : "Ola mundo",
    "description" : "esse e um teste",
    "discipline" : "5d8fb8e04becf712f8293b5b",
    "createdAt" : "2019-10-01T23:22:23.168Z",
    "__v" : 0
}

现在您加入了文档,您可以使用 $addFields 和 $filter 按 "official" 字段过滤它。 $addFields 将新字段添加到文档 https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/。在此解决方案中,我使用相同的字段名称 "answer",它将用过滤后的文档覆盖答案数组。

{
    $addFields: {
        answer: {
            $filter: {
                input: "$answer",
                as: "answer",
                cond: { $eq: [ "$$answer.official", true ] }
            }
        }

    }
}

结果将是:

{
    "_id" : ObjectId("5d93dfaf40024619dcc61896"),
    "solved" : false,
    "answer" : [
        {
            "_id" : ObjectId("5d969f7b7d496a256443eecb"),
            "official" : true,
            "description" : "Esste e um teeeeste",
            "createdAt" : "2019-10-04T01:25:15.829Z",
            "__v" : 0
        }
    ],
    "user" : "5d8963afa0014a289c8d7112",
    "title" : "Ola mundo",
    "description" : "esse e um teste",
    "discipline" : "5d8fb8e04becf712f8293b5b",
    "createdAt" : "2019-10-01T23:22:23.168Z",
    "__v" : 0
}

这是完整的查询:

db.Question.aggregate([
{
    $lookup: {
        from: "Answer",
        foreignField: "_id",
        localField: "answer",
        as: "answer"
    }

},
{
    $addFields: {
        answer: {
            $filter: {
                input: "$answer",
                as: "answer",
                cond: { $eq: [ "$$answer.official", true ] }
            }
        }

    }
}])

看起来您已经在使用 mongoose,因此您可以使用 populate with query condition 来解决您的问题。类似于:

Question.find(...).populate({
  path: 'answer',
  match: { official: true}
})