MongoDB 如何在嵌套数组中过滤

MongoDB how to filter in nested array

我有以下数据。我想在属于 name=name2 的内部数组中找到 value=v2(删除不等于 v2 的其他值)。如何为此编写聚合?对我来说最难的部分是过滤只属于 name=name2.

nestedArray
{
  "_id": 1,
  "array": [
    {
      "name": "name1",
      "nestedArray": [
        {
          "value": "v1"
        },
        {
          "value": "v2"
        }
      ]
    },
    {
      "name": "name2",
      "nestedArray": [
        {
          "value": "v1"
        },
        {
          "value": "v2"
        }
      ]
    }
  ]
}

所需的输出如下。请注意 value=v1 保留在 name=name1 下,而 value=v1 下的 name=name2 已删除。

{
  "_id": 1,
  "array": [
    {
      "name": "name1",
      "nestedArray": [
        {
          "value": "v1"
        },
        {
          "value": "v2"
        }
      ]
    },
    {
      "name": "name2",
      "nestedArray": [
        {
          "value": "v2"
        }
      ]
    }
  ]
}

您可以使用以下聚合查询:

db.collection.aggregate([
  {
    $project: {
      "array": {
        "$concatArrays": [
          {
            "$filter": {
              "input": "$array",
              "as": "array",
              "cond": {
                "$ne": [
                  "$$array.name",
                  "name2"
                ]
              }
            }
          },
          {
            "$filter": {
              "input": {
                "$map": {
                  "input": "$array",
                  "as": "array",
                  "in": {
                    "name": "$$array.name",
                    "nestedArray": {
                      "$filter": {
                        "input": "$$array.nestedArray",
                        "as": "nestedArray",
                        "cond": {
                          "$eq": [
                            "$$nestedArray.value",
                            "v2"
                          ]
                        }
                      }
                    }
                  }
                }
              },
              "as": "array",
              "cond": {
                "$eq": [
                  "$$array.name",
                  "name2"
                ]
              }
            }
          }
        ]
      }
    }
  }
])

MongoDB Playground

你可以试试,

  • $set 更新 array 字段,$map 迭代 array 字段的循环,检查条件如果名称是 name2 然后 $filter 得到来自 nestedArray 字段的匹配值 v2 文档和 $mergeObject 将对象与可用对象合并
let name = "name2", value = "v2";
db.collection.aggregate([
  {
    $set: {
      array: {
        $map: {
          input: "$array",
          in: {
            $mergeObjects: [
              "$$this",
              {
                $cond: [
                  { $eq: ["$$this.name", name] }, //name add here
                  {
                    nestedArray: {
                      $filter: {
                        input: "$$this.nestedArray",
                        cond: { $eq: ["$$this.value", value] } //value add here
                      }
                    }
                  },
                  {}
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Playground