在 child 个元素上使用 elemMatch 进行投影和过滤

Project and filter using elemMatch on child elements

这是我collection的内容:

[{
  "_id": {
    "$oid": "61b253a89e51973f978b818d"
  },
  "id": 1,
  "level1": [
    {
      "name": "child11",
      "level2": [
        {
          "name": "chil21"
        },
        {
          "name": "chilxx"
        }
      ]
    },
    {
      "name": "child12",
      "level2": [
        {
          "name": "chil23"
        },
        {
          "name": "chil24"
        }
      ]
    }
  ]
},{
  "_id": {
    "$oid": "61b254b69e51973f978b818e"
  },
  "id": 2,
  "level1": [
    {
      "name": "child13",
      "level2": [
        {
          "name": "chil25"
        },
        {
          "name": "chil26"
        }
      ]
    },
    {
      "name": "child14",
      "level2": [
        {
          "name": "chil27"
        },
        {
          "name": "chil28"
        },
        {
          "name": "chilxx"
        },
        {
          "name": "chil2a"
        }
      ]
    }
  ]
}]

我现在想要聚合这样

因此,预期的聚合输出应该是:

[{
  "_id": {
    "$oid": "61b253a89e51973f978b818d"
  },
  "id": 1,
  "level1": [
    {
      "name": "child11",
      "level2": [
        {
          "name": "chil21"
        },
        {
          "name": "chilxx"
        }
      ]
    }
  ]
},{
  "_id": {
    "$oid": "61b254b69e51973f978b818e"
  },
  "id": 2,
  "level1": [
    {
      "name": "child14",
      "level2": [
        {
          "name": "chil27"
        },
        {
          "name": "chil28"
        },
        {
          "name": "chilxx"
        },
        {
          "name": "chil2a"
        }
      ]
    }
  ]
}]

这是我的(无效的)聚合方法:

[
  {
    '$match': {}
  }, {
    '$project': {
      '_id': 1, 
      'id': 1, 
      'level1': {
        '$filter': {
          'input': '$level1', 
          'as': 'l1', 
          'cond': {
            '$$l1.level2': {
              '$elemMatch': {
                'name': 'chilxx'
              }
            }
          }
        }
      }
    }
  }
]

但是,这会导致错误:

Invalid $project :: caused by :: Unrecognized expression '$$l1.level2'

提前致谢。

  • $match
  • $set
db.collection.aggregate([
  {
    "$match": {
      "level1.level2.name": "chilxx"
    }
  },
  {
    "$set": {
      "level1": {
        "$filter": {
          "input": "$level1",
          "as": "first",
          "cond": {
            $ne: [
              {
                "$filter": {
                  "input": "$$first.level2",
                  "as": "second",
                  "cond": {
                    $eq: [
                      "$$second.name",
                      "chilxx"
                    ]
                  }
                }
              },
              []
            ]
          }
        }
      }
    }
  }
])

mongoplayground