MongoDB 在子文档中查找

MongoDB find among subdocuments

我有一堆文档,每个文档的格式都是这样的:

{
  "faculty": "Some Faculty",
  "students": [
      {
        "id": "51230867123",
        "age": "21",
        "name": "awdawdawdawawd"
      },
      {
        "id": "0217356102",
        "age": "22",
        "name": "awdawd"
      },
      ...
      ]
}

我已经使用 insertMany([...]) 将这些文档插入到单个 MongoDB 集合中,所以现在我的 students table 看起来像这样:

{
  "faculty": "Some Faculty",
  "students": [
      {
        "id": "51230867123",
        "age": "21",
        "name": "John Doe"
      },
      {
        "id": "0217356102",
        "age": "22",
        "name": "Jane Doe"
      },
      ...
      ]
},
{
  "faculty": "Other Faculty",
  "students": [
      {
        "id": "1240876124",
        "age": "21",
        "name": "Jimmy Doe"
      },
      {
        "id": "2309857120578",
        "age": "22",
        "name": "Johnny Doe"
      },
      ...
      ]
},
...

我非常想了解如何对某些子文档执行 find 查询,特别是 students。例如,我想 find 所有 students.namestudents.age > 23。我尝试了很多查询,包括 db.students.find({"students.age": {$gt: /.*B.*/}}, {_id: 0, "students.name": 1}),但此类查询总是 return 至少有一名学生满足条件的整个文档。我想查询个别学生。这可能使用 find(没有 aggregate)吗?

使用aggregate,可以使用unwrap,这正是我需要做的。然而,我希望有一些技巧可以与 find 一起使用来实现这种行为。

从MongoDB4.2开始,find和findOne方法的projection中可以使用聚合运算符,

  • $filter 迭代学生数组循环并检查所需条件,它将 return 过滤结果
  • $map 迭代上述过滤结果的循环并且 return 仅 name
db.collection.find(
  { "students.age": { $gt: "23" } },
  {
    "students": {
      $map: {
        input: {
          $filter: {
            input: "$students",
            cond: { $gt: ["$$this.age", "23"] }
          }
        },
        in: "$$this.name"
      }
    }
  }
)

Playground