【问题标题】:How to perform $match after $lookup in mongoDB如何在 mongoDB 中 $lookup 后执行 $match
【发布时间】:2021-09-16 15:13:19
【问题描述】:

这里有两个收藏

类别

[
    {
      id: 1,
      name: "MEN",
      status: true
    },
    {
      id: 2,
      name: "WOMEN",
      staus: true
    }
  ]

服务

[
    {
      name: "service a",
      category_id: 1,
      status: true
    },
    {
      name: "service b",
      category_id: 1,
      status: true
    },
    {
      name: "service c",
      category_id: 1,
      status: true
    },
    {
      name: "service d",
      category_id: 1,
      status: false
    }
  ]

我希望该类别中的所有服务都明智。为此,我使用了lookup 侵略。我又添加了一个攻击阶段来过滤状态为 true 的服务。

我尝试了以下方法。

db.category.aggregate([
  {
    "$lookup": {
      "from": "services",
      "localField": "id",
      "foreignField": "category_id",
      "as": "services"
    }
  },
  {
    "$match": {
      "services.status": true
    }
  }
])

预期输出

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "id": 1,
    "name": "MEN",
    "services": [
      {
        "_id": ObjectId("5a934e000102030405000002"),
        "category_id": 1,
        "name": "service a",
        "status": true
      },
      {
        "_id": ObjectId("5a934e000102030405000003"),
        "category_id": 1,
        "name": "service b",
        "status": true
      },
      {
        "_id": ObjectId("5a934e000102030405000004"),
        "category_id": 1,
        "name": "service c",
        "status": true
      },
    ],
    "status": true
  }
]

看看https://mongoplayground.net/p/FXNakB7cLse

【问题讨论】:

    标签: mongodb mongoose mongodb-query


    【解决方案1】:

    您有多种选择。

    使用您的数据,您可以在项目阶段简单地使用$filter,如下所示:

    db.category.aggregate([
      {
        "$lookup": {
          "from": "services",
          "localField": "id",
          "foreignField": "category_id",
          "as": "services"
        }
      },
      {
        "$project": {
          "id": 1,
          "name": 1,
          "status": 1,
          "services": {
            "$filter": {
              "input": "$services",
              "as": "s",
              "cond": {
                "$eq": [
                  "$$s.status",
                  true
                ]
              }
            }
          }
        }
      }
    ])
    

    例如here

    其他选项是使用以下条件执行$lookup

    db.category.aggregate([
      {
        "$lookup": {
          "from": "services",
          "let": {
            "id": "$id"
          },
          "pipeline": [
            {
              "$match": {
                "$expr": {
                  "$and": [
                    {
                      "$eq": [
                        "$category_id",
                        "$$id"
                      ]
                    },
                    {
                      "$eq": [
                        "$status",
                        true
                      ]
                    }
                  ]
                }
              }
            }
          ],
          "as": "services"
        }
      }
    ])
    

    例如here

    最后一个选项(我不建议这样做)是使用$unwind$match$group:例如here

    另外,如果您不想获取services: [] 所在的文档,您可以在前两个选项中添加$match 阶段:

    {
      "$match": {
        "services": {
          "$ne": []
        }
      }
    }
    

    【讨论】:

    • 打败我,+1 :)
    猜你喜欢
    • 2022-07-09
    • 2016-11-14
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2022-11-22
    • 2020-03-15
    相关资源
    最近更新 更多