我有这样的数据:
[
{ "grp": "A", "seq": 1, "score": 1, x: 0 },
{ "grp": "A", "seq": 1, "score": 2, x: 0 },
{ "grp": "A", "seq": 1, "score": 3, x: 0 },
{ "grp": "A", "seq": 1, "score": 4, x: 0 }
]
$setWindowFields
,
{
partitionBy: "$grp",
sortBy: { seq: 1 },
output: {
x: {
$sum: "$score",
window: {
documents: ["unbounded", "current"]
}
},
}
}
我得到:
[
{ "grp": "A", "seq": 1, "score": 1, x: 1 },
{ "grp": "A", "seq": 1, "score": 2, x: 3 },
{ "grp": "A", "seq": 1, "score": 3, x: 6 },
{ "grp": "A", "seq": 1, "score": 4, x: 10 }
]
我只需要保留分区的
最后一项的运行总和(
x
)。
[
{ "grp": "A", "seq": 1, "score": 1, x: 0 },
{ "grp": "A", "seq": 1, "score": 2, x: 0 },
{ "grp": "A", "seq": 1, "score": 3, x: 0 },
{ "grp": "A", "seq": 1, "score": 4, x: 10 }
]
我一直在使用
$project
和 $last
进行测试,但我无法使其工作。
我需要使用什么更好的表达或额外的阶段?
谢谢!
不确定您的数据集中是否存在确定性排序,但使用与您使用的相同排序,您可以在
ordering
中将 $documentNumber
与 $setWindowFields
一起分配。然后,使用 $rank
字段计算 ordering
。最后一个文档将有 rank: 1
。您可以将其与 $cond
一起使用来有条件地设置字段 x
db.collection.aggregate([
{
"$setWindowFields": {
partitionBy: "$grp",
sortBy: {
seq: 1
},
output: {
x: {
$sum: "$score",
window: {
documents: [
"unbounded",
"current"
]
}
},
ordering: {
$documentNumber: {}
}
}
}
},
{
"$setWindowFields": {
"partitionBy": "$grp",
"sortBy": {
"ordering": -1
},
"output": {
"rank": {
"$rank": {}
}
}
}
},
{
"$set": {
"ordering": "$$REMOVE",
"rank": "$$REMOVE",
"x": {
"$cond": {
"if": {
$eq: [
1,
"$rank"
]
},
"then": "$x",
"else": 0
}
}
}
}
])