在筛选聚合中选择嵌套字段

Select nested fields in filtered aggregation

提问人:Marc Grue 提问时间:11/6/2023 最后编辑:Marc Grue 更新时间:11/6/2023 访问量:49

问:

如何聚合、过滤嵌套数组并投影选定的嵌套字段?

我有以下数据:

{
  "teacher": "Ben",
  "students": [
    {
      "name": "Liz",
      "age": 8,
      "pets": 1
    },
    {
      "name": "Jon",
      "age": 9,
      "pets": 3
    },
    {
      "name": "Eva",
      "age": 9,
      "pets": 2
    }
  ]
}

..并希望查询以获取此结果:

{
  "teacher": "Ben",
  "students": [
    {
      "name": "Jon",
      "pets": 3
    },
    {
      "name": "Eva",
      "pets": 2
    }
  ]
}

我可以按年龄进行筛选,但如何仅返回嵌套学生数据中的 and 字段?在没有运气的情况下,我试图以我能想到的所有方式投射这些领域,所以我可能找错了地方。namepets

db.classes.aggregate([
  { "$match": {} },
  { "$project": {
    "_id": 0,
    "teacher": 1,
    "students": {
      "$filter": {
        input: "$students",
        cond: {
          "$eq": [ "$$this.age", 9 ],
        }
      }
    }
  }}
])
mongodb mongodb-查询 聚合框架

评论


答:

1赞 cmgchess 11/6/2023 #1

您可以添加一个阶段$project

 //previous stages 
 {
    $project: {
      "students.age": 0
    }
  }

或者,您可以使用$unset阶段删除不需要的字段

db.collection.aggregate([
  { $match: {} },
  {
    $project: {
      _id: 0,
      teacher: 1,
      students: {
        $filter: {
          input: "$students",
          cond: { $eq: [ "$$this.age", 9 ] }
        }
      }
    }
  },
  { $unset: "students.age" }
])

操场

我认为如果后面跟着一个,它会更干净$addFields$unset

db.collection.aggregate([
  { $match: {} },
  {
    $addFields: {
      students: {  //fields you just want to add, here overwrites students
        $filter: {
          input: "$students",
          cond: { $eq: [ "$$this.age", 9 ] }
        }
      }
    }
  },
  { $unset: [ "students.age", "_id" ] } //remove just the ones not needed
])

操场

评论

0赞 Marc Grue 11/6/2023
非常好!像魅力一样工作。感谢所有的变化,@cmgchess!