首页 > 解决方案 > MongoDB 中的子查询,用于返回具有特定字段的单个元素

问题描述

我有两个集合,其中一个有一个带有另一个 ID 的数组。我需要返回第一个集合中的一个元素和第二个集合中的一个元素,但只返回具有特定字段的元素。我会澄清一下。

我试图用它做一些事情,但不能完全理解操作。 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
}

我需要返回问题模型和“官方”字段等于“真”的 Awnser 模型。我是 mongoDB 的新手,所以我正在寻求帮助。我认为sql中可能有类似子查询的东西。

标签: mongodbjoinmongooseobjectid

解决方案


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

您需要使用 $lookup 将 answer 数组中的所有 id 加入到 Answer 集合中,然后使用 $filter 按“官方”对其进行过滤。

如果 _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 按“官方”字段对其进行过滤。$addFields 向文档https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/添加一个新字段。在此解决方案中,我使用相同的字段名称“答案”,它将用过滤后的文档覆盖答案数组。

{
    $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 ] }
            }
        }

    }
}])

推荐阅读