Arrays Mongo筛选/查找嵌入数组中符合条件的所有元素并返回周围文档?

Arrays Mongo筛选/查找嵌入数组中符合条件的所有元素并返回周围文档?,arrays,mongodb,filter,document,Arrays,Mongodb,Filter,Document,基本上,我有一个具有以下结构的Mongo DB: [ { "id": 1, "other_thing": "whatever", "annoying_array": [ { "sub_id": "a", "thing_type": "apple" },

基本上,我有一个具有以下结构的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({happing.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"
      }
    ]
  }
]
这似乎很有意义,但已经有将近10年的历史了,我知道从那个以后,大量的过滤/聚合管道都发生了变化。可能有一种更干净的方法

我已经尝试了我所能想到的一切,从
find
match
elemMatch
,但一切都返回存在
thing类型的所有文档和子数组:“pear”
,而不是子数组中
thing\u type=pear
的所有元素。即使它没有返回周围的元数据(即不包括
其他东西
,等等),我也会满足于只返回键与特定值匹配的每个元素(子文档)


还可以选择返回作为自己文档匹配的
数组
的每个匹配元素,并将文档范围的数据(即
id
,或
其他东西
)投影到每个匹配项。

您可以使用
聚合管道

  • $match
    查找
    数组
    包含
    对象类型
    属性等于
    pear
    的项目的所有文档
  • $project
    指定要从结果返回的属性
  • $filter
    仅过滤
    数组中
    类型
    属性等于
    pear
    的项目

这是正在工作的exmaple:

看起来很有效!我用一个
匹配
阶段和一个
项目
阶段测试了它。现在我只需要把它翻译成Pymongo,但这是一个不同的问题。谢谢如果您想将
恼人数组
中的每个元素作为自己的文档返回,并将文档范围内的元数据(即project
other\u thing
等)添加到
恼人数组
中匹配的每个元素,并将每个元素作为单独的文档返回,您是否有可能修改您的答案,但是您应该为此创建一个新问题,因为在这个问题中您指定了所需的输出。因此,由于未来的访问者会提出一个新问题,并在此处发布其链接。以下是更新的答案:
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"
            ]
          }
        }
      }
    }
  }
])