Mongodb 如何过滤两层深度的数组元素?

Mongodb 如何过滤两层深度的数组元素?,mongodb,aggregation-framework,pymongo,Mongodb,Aggregation Framework,Pymongo,在我的集合中,我有一个数组,里面有对象,里面有数组。我的数据如下所示: { 'settings': { 'labourContributions': [ { 'show': True, 'Accrual': True, '_id': ObjectId('abc'), 'name': 'Holidays', 'amount': 10, 'target': [

在我的集合中,我有一个数组,里面有对象,里面有数组。我的数据如下所示:

{
  'settings': {
    'labourContributions': [
      {
        'show': True,
        'Accrual': True,
        '_id': ObjectId('abc'),
        'name': 'Holidays',
        'amount': 10,
        'target': [
          {
            'date': 2021-05-17T23: 00: 00.000+00: 00,
            'percent': 4.0
          },
          {
            'date': 2021-05-19T23: 00: 00.000+00: 00,
            'percent': 10.0
          }
        ]
      },
      {
        'show': True,
        'Accrual': True,
        '_id': ObjectId('abd'),
        'name': 'Taxes',
        'amount': 10,
        'target': [
          {
            'date': 2021-04-01T23: 00: 00.000+00: 00,
            'percent': 8.0
          },
          {
            'date': 2021-05-27T23: 00: 00.000+00: 00,
            'percent': 10.0
          }
        ]
      }
    ]
  }
}
我的目标是根据一些匹配返回
labourContributions
的所有元素,但在
labourContributions中。target
我只需要一个元素,根据其他一些匹配(比如
percent
>5)

使用聚合管道尝试此操作,目前为止我只能做到:

c = collection.aggregate([
  {
    "$match": {
      "settings.labourContributions": {
        "$elemMatch": {
          "Accrual": True
        }
      }
    }
  },
  {
    "$project": {
      "settings.labourContributions.$.target": {
        "$filter": {
          "input": "$settings.labourContributions.$.target",
          "as": "contributions",
          "cond": {
            "$gt": [
              "$$contributions.percent",
              5
            ]
          }
        }
      }
    }
  }
])
我认为
$项目
阶段不能支持
$
阵列切片。如何基于我的深层数组进行查询

我认为
$项目
阶段不能支持
$
阵列切片。如何基于我的深层数组进行查询

您只能在更新查询中使用
$
位置

  • $match
    使用嵌套的
    $elemMatch
  • $filter
    迭代
    劳动贡献的循环
    ,并根据
    应计
    条件过滤主要文档
  • $map
    迭代上述过滤文档的循环
  • $filter
    迭代
    target
    数组的循环,并按
    percent
  • $mergeObjects
    合并地图的当前对象和过滤后的
    目标
    数组

c = collection.aggregate([
  {
    $match: {
      "settings.labourContributions": {
        $elemMatch: {
          Accrual: true,
          target: {
            $elemMatch: {
              percent: { $gt: 5 }
            }
          }
        }
      }
    }
  },
  {
    $project: {
      "settings.labourContributions": {
        $map: {
          input: {
            $filter: {
              input: "$settings.labourContributions",
              cond: { $eq: ["$$this.Accrual", true] }
            }
          },
          in: {
            $mergeObjects: [
              "$$this",
              {
                target: {
                  $filter: {
                    input: "$$this.target",
                    cond: { $gt: ["$$this.percent", 5] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])