如何过滤两层深阵列的阵列元素



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

{
'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阶段不能支持$阵列切片。如何基于更深层次的数组进行查询?

我认为$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] }
}
}
}
]
}
}
}
}
}
])

游乐场

最新更新