首页 > 解决方案 > 如何使用 $filter 从嵌套数组中检索结果?

问题描述

我正在尝试使用 MongoDB 构建查询,但是我遇到了一个问题,即我无法在数组中过滤数组。

在下面的示例中,我试图检索datalist数组中子数组中的元素,其中键systemDelete_DTnull.

我试图$eq: ["$$s_lists.customData.systemDelete_DT", null]用作过滤条件,但是没有结果加载。

我正在使用$filter,因为这是带有$lookup.

如何仅从键所在的数组data中检索结果?systemDelete_DTnull

现场示例

我的查询

    db.collection.aggregate([
  {
    $lookup: {
      from: "s_list",
      localField: "_id",
      foreignField: "_id",
      as: "s_lists"
    }
  },
  {
    $project: {
      list: {
        $filter: {
          input: {
            $arrayElemAt: [
              "$s_lists.list",
              0
            ]
          },
          as: "s_lists",
          cond: {
           **// Note: This condition works as expected** 
            $eq: [
              "$$s_lists.systemDelete_DT",
              null
            ],
            
          }
        }
      }
    }
  }
])

预期结果:

 [
      {
        "_id": ObjectId("6099619baa04f15c3fb67a83"),
        "list": [
          {
            "_id": ObjectId("609e70be503c58506ca77d3d"),
            "data": [
              {
                "_id": ObjectId("609e70be503c58506ca77d41"),
                "field_id": ObjectId("609c00d6de4c601e4fa358d8"),
                "systemDelete_DT": null
              },
              {
                "_id": ObjectId("609e936024c6a45adc030a4c"),
                "field_id": ObjectId("609e936024c6a45adc030a4b"),
                "systemDelete_DT": null
              }
            ],
            "systemDelete_DT": null
          }
        ]
      }
    ]

数据库示例:

db={
  "collection": [
    {
      "_id": ObjectId("6099619baa04f15c3fb67a83")
    }
  ],
  "s_list": [
    {
      "_id": ObjectId("6099619baa04f15c3fb67a83"),
      "systemDelete_DT": null,
      "list": [
        {
          "_id": ObjectId("609e6ee1955f7b4fbd73fcb5"),
          "systemDelete_DT": "2021-05-14T18:13:18+01:00",
          "data": [
            {
              "_id": ObjectId("609e6ee1955f7b4fbd73fcb6"),
              "systemDelete_DT": "2021-05-14T18:13:18+01:00",
              "field_id": ObjectId("609bbeb0f1033c156f8e4d86"),
              
            },
            {
              "_id": ObjectId("609e6ee1955f7b4fbd73fcb9"),
              "systemDelete_DT": null,
              "field_id": ObjectId("609c00d6de4c601e4fa358d8"),
              
            },
            {
              "_id": ObjectId("609e936024c6a45adc030a4c"),
              "systemDelete_DT": null,
              "field_id": ObjectId("609e936024c6a45adc030a4b"),
              
            }
          ]
        },
        {
          "_id": ObjectId("609e70be503c58506ca77d3d"),
          "systemDelete_DT": null,
          "data": [
            {
              "_id": ObjectId("609e70be503c58506ca77d3e"),
              "systemDelete_DT": "2021-05-14T18:13:18+01:00",
              "field_id": ObjectId("609bbeb0f1033c156f8e4d86"),
              
            },
            {
              "_id": ObjectId("609e70be503c58506ca77d41"),
              "systemDelete_DT": null,
              "field_id": ObjectId("609c00d6de4c601e4fa358d8"),
              
            },
            {
              "_id": ObjectId("609e936024c6a45adc030a4c"),
              "systemDelete_DT": null,
              "field_id": ObjectId("609e936024c6a45adc030a4b"),
              
            }
          ]
        }
      ]
    }
  ]
}

标签: node.jsmongodbaggregation-framework

解决方案


  • $filters_lists.list在使用选择第一个元素后迭代数组循环并过滤空元素$arrayElemAt
  • $map迭代上述过滤列表结果的循环
  • $filter迭代内部数组的循环data并过滤空元素
  • $mergeObjects将当前字段与data上述过滤器中的更新字段合并
  {
    $project: {
      list: {
        $map: {
          input: {
            $filter: {
              input: { $arrayElemAt: ["$s_lists.list", 0] },
              cond: { $eq: ["$$this.systemDelete_DT", null] }
            }
          },
          in: {
            $mergeObjects: [
              "$$this",
              {
                data: {
                  $filter: {
                    input: "$$this.data",
                    cond: { $eq: ["$$this.systemDelete_DT", null] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }

操场


推荐阅读