[英]How to nested sum in mongodb
我有这个方案:
[{
name: 'John',
plays: [{
playNum: 1,
song: {
length: 400,
param: 'a'
}
}, {
playNum: 2,
song: {
length: 350,
param: 'a'
}
}, {
playNum: 3,
song: {
length: 211,
param: 'a'
}
]
},
{
name: 'John',
plays: [{
playNum: 2,
song: {
length: 400,
param: 'a'
}
}, {
playNum: 3,
song: {
length: 350,
param: 'a'
}
}, {
playNum: 4,
song: {
length: 211,
param: 'a'
}
]
}
]
我想计算特定播放的时间,例如,播放2-我们有一首歌在350中,另一首在400 = 750中。
我试图这样做:
aggregate(
{$match : { "shows.showNum" : showNum } },
{$unwind : "$shows"},
{$group : {_id : "$shows.showNum", totalLength : { $sum : "$shows.song.length" }}})
但是通过这种方式,我获得了该演出中播放的所有歌曲的总数。
有人可以帮忙吗?
谢谢!
您的第一个$match
只匹配包含数组中该值的“文档”。 要真正“过滤”数组内容,在管道中$unwind
之后,您还需要另一个$match
:
db.collection.aggregate([
{ "$match": { "plays.playNum" : playNum } },
{ "$unwind": "$plays"},
{ "$match": { "plays.playNum" : playNum } },
{ "$group": {
"_id" : "$plays.playNum",
"totalLength": { "$sum" : "$plays.song.length" }
}}
])
如果您拥有MongoDB 2.6或更高版本,则实际上可以使用$map
运算符和其他辅助运算符来过滤数组:
db.collection.aggregate([
{ "$match": { "plays.playNum" : playNum } },
{ "$project": {
"plays": {
"$setDifference": [
{
"$map": {
"input": "$plays",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.playNum", playNum ] },
"$$el",
false
]
}
}
],
[false]
]
}
}},
{ "$unwind": "$plays" },
{ "$group": {
"_id" : "$plays.playNum",
"totalLength": { "$sum" : "$plays.song.length" }
}}
])
通过组合各个阶段的功能,可以使事情更快一些。 它看起来更复杂,但实际上是处理最终结果的最快方法。
db.collection.aggregate([
{$unwind: '$plays'},
{$match: {"plays.playNum" : 2} },
{$group: {
_id: null,
"suma": {$sum: "$song.length" }
}}
])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.