【问题标题】:How to Filter Array Elements for Arrays Two Levels Deep?如何过滤两层深度的数组的数组元素?
【发布时间】:2021-08-09 14:26:06
【问题描述】:

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

{
  '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
            ]
          }
        }
      }
    }
  }
])

我不认为$project 阶段可以支持$ 数组切片。如何根据更深的数组进行查询?

【问题讨论】:

    标签: mongodb aggregation-framework pymongo


    【解决方案1】:

    我不认为$project 阶段可以支持$ 数组切片。如何根据更深的数组进行查询?

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

    • $match 你的两个条件都使用嵌套的$elemMatch
    • $filter 循环labourContributions 并通过Accrual 条件过滤主文档
    • $map 迭代上述过滤文档的循环
    • $filter 迭代 target 数组的循环并通过 percent 过滤文档
    • $mergeObjects合并当前地图对象和过滤target数组
    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] }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    ])
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 2014-01-05
      • 2017-03-05
      • 2019-05-29
      • 1970-01-01
      • 2017-11-26
      • 1970-01-01
      相关资源
      最近更新 更多