Mongodb 基于另一个数组元素过滤数组



假设我有如下文档

{
"_id" : 1,
"Quality" : [ 
"HIGH", 
"LOW", 
"LOW", 
"HIGH"
],
"Pages" : [ 
10, 
10, 
12, 
17
]
}

我需要结果作为

{
"_id" : 1,
"HIGH" : 27
"LOW" : 22
}

我需要根据质量创建两个属性 HIGH 和 LOW,方法是将它们对应的 Pages 数组索引位置值相加。

我虽然使用$filter$arrayElemAt,但在过滤页面属性时无法获得索引位置

high : { $sum:{ $filter: { input: "$Pages", as: "noOfPages", cond: {"$eq":[{ $arrayElemAt: ["$Quality", **Need to pass index position of $pages while filtering**]}, "HIGH"]}}}}

提前谢谢。

您可以使用以下聚合

db.collection.aggregate([
{ "$project": {
"Quality": {
"$map": {
"input": { "$range": [0, { "$size": "$Quality" }] },
"in": {
"Quality": { "$arrayElemAt": ["$Quality", "$$this"] },
"Pages": { "$arrayElemAt": ["$Pages", "$$this"] }
}
}
}
}},
{ "$project": {
"newArrayField": {
"$map": {
"input": { "$setUnion": ["$Quality.Quality"] },
"as": "m",
"in": {
"k": "$$m",
"v": {
"$filter": {
"input": "$Quality",
"as": "d",
"cond": {
"$eq": ["$$d.Quality", "$$m"]
}
}
}
}
}
}
}},
{ "$project": {
"d": {
"$arrayToObject": {
"$map": {
"input": "$newArrayField",
"in": {
"k": "$$this.k",
"v": { "$sum": "$$this.v.Pages" }
}
}
}
}
}}
])

蒙戈游乐场

可以通过 2 个聚合阶段来实现这一点。

首先是将 2 个数组映射到单个数组中。

其次是过滤单个数组以仅包含 HIGH(/LOW(,并将过滤后的数组减少为单个 sum 元素。

[{$project: {
"Quality": {
$map: {
input: {$range: [0, {$size: "$Quality"}]},
as: "idx",
in: {
"Quality": { $arrayElemAt: ["$Quality", "$$idx"] },
"Pages": { $arrayElemAt: ["$Pages", "$$idx"] }
}
}
}
}}, {$project: {
"HIGH": {
$reduce: {
input: {
$filter: {
input: "$Quality",
as: "x",
cond: {$eq: ["$$x.Quality", "HIGH"]}
}
},
initialValue: 0,
in: {
$add: ["$$value", "$$this.Pages"]
}
}
},
"LOW": {
$reduce: {
input: {
$filter: {
input: "$Quality",
as: "x",
cond: {$eq: ["$$x.Quality", "LOW"]}
}
},
initialValue: 0,
in: {
$add: ["$$value", "$$this.Pages"]
}
}
}
}}]

这恰恰给出了您所要求的:

{
_id: 1
HIGH:27
LOW:22
}

最新更新