【问题标题】:How to use $filter to retrieve results from a nested array?如何使用 $filter 从嵌套数组中检索结果?
【发布时间】:2021-05-14 19:39:40
【问题描述】:

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

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

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

我正在使用$filter,因为这是带有$lookup 的较大聚合的一部分。

如何仅从 systemDelete_DT 键为 nulldata 数组中检索结果?

Live Example

我的查询

    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.js mongodb aggregation-framework


    【解决方案1】:
    • $filter 在使用 $arrayElemAt 选择第一个元素后迭代 s_lists.list 数组的循环并过滤空元素
    • $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] }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2018-12-15
      • 1970-01-01
      • 2018-04-14
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多