【问题标题】:Mongo filter/find all elements in embedded array that match a criteria and return surrounding documents?Mongo过滤/查找嵌入式数组中匹配条件并返回周围文档的所有元素?
【发布时间】:2021-06-01 19:20:11
【问题描述】:

基本上,我有一个具有以下结构的 Mongo DB:

[
  {
    "id": 1,
    "other_thing": "whatever",
    "annoying_array": [
      {
        "sub_id": "a",
        "thing_type": "apple"
      },
      {
        "sub_id": "b",
        "thing_type": "pear"
      }
    ]
  },
  {
    "id": 2,
    "other_thing": "whatever_else",
    "annoying_array": [
      {
        "sub_id": "c",
        "thing_type": "carrot"
      },
      {
        "sub_id": "d",
        "thing_type": "pear"
      },
      {
        "sub_id": "e",
        "thing_type": "pear"
      }
    ]
  }
]

我基本上想做类似db.docs.find( {annoying.array.thing_type: "pear"}) 的事情并让它返回:

[
  {
    "id": 1,
    "other_thing": "whatever",
    "annoying_array": [
      {
        "sub_id": "b",
        "thing_type": "pear"
      }
    ]
  },
  {
    "id": 2,
    "other_thing": "whatever_else",
    "annoying_array": [
      {
        "sub_id": "d",
        "thing_type": "pear"
      },
      {
        "sub_id": "e",
        "thing_type": "pear"
      }
    ]
  }
]

This question 似乎相关,但已经有将近 10 年的历史了,而且我知道从那时起大量的过滤器/聚合管道发生了变化。可能有一种更清洁的方法。

我已经尝试了所有我能想到的东西,从 findmatchelemMatch,但所有东西都会返回所有 存在 thing_type: 'pear' 的文档和子数组,而不是thing_type = pear 的子数组中的每个元素。即使它没有返回周围的元数据(即不包括other_thing 等),我也会满足于返回键与特定值匹配的每个元素(子文档)强>。

如果可以选择返回 annoying_array 的每个匹配元素作为其自己的文档匹配,并将文档范围的数据(即 idother_thing)投影到每个匹配。

【问题讨论】:

    标签: arrays mongodb filter document


    【解决方案1】:

    你可以使用Aggregation Pipeline:

    • $match 查找 annoying_array 包含 thing_type 属性等于 pear 的项目的所有文档。
    • $project 指定要从结果中返回的属性
    • $filter 仅过滤 annoying_arraything_type 属性等于 pear 的那些项目。
    db.collection.aggregate([
      {
        "$match": {
          "annoying_array.thing_type": "pear"
        }
      },
      {
        "$project": {
          "id": 1,
          "other_thing": 1,
          "annoying_array": {
            "$filter": {
              input: "$annoying_array",
              as: "item",
              cond: {
                "$eq": [
                  "$$item.thing_type",
                  "pear"
                ]
              }
            }
          }
        }
      }
    ])
    

    这是工作示例:https://mongoplayground.net/p/7bLcScBQv8c

    【讨论】:

    • 看起来这行得通!我测试了 Compass 有一个match 阶段和一个project 阶段。现在我只需要将它翻译成 Pymongo,但这是一个不同的问题。谢谢!
    • 如果您想将annoying_array 的每个元素作为自己的文档返回,您可以修改答案以包含任何机会,并附上文档范围的元数据,即项目other_thing 等到每个元素匹配annoying_array并将每个元素作为单独的文档返回?
    • 是的,但是您应该为此创建一个新问题,因为在此问题中您指定了所需的输出。因此,由于未来的访问者创建了一个新问题并在此处发布其链接。
    • 这是更新后的答案:mongoplayground.net/p/8XmG9VMzubA
    猜你喜欢
    • 2019-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 2016-07-13
    • 2022-06-13
    • 2015-07-01
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多