我有这个计划:
[{
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" }}})
但是通过这种方式,我得到了在该节目中播放的所有歌曲的总数。
任何人都可以帮忙吗?
谢谢!
答案 0 :(得分:2)
您的第一个$match
仅匹配数组中包含该值的“文档”。要实际“过滤”数组内容,您需要在管道中$match
之后另外$unwind
:
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" }
}}
])
通过组合各个阶段的功能,使事情变得更快。它看起来更复杂,但实际上是处理最终结果的最快方式。
答案 1 :(得分:0)
db.collection.aggregate([
{$unwind: '$plays'},
{$match: {"plays.playNum" : 2} },
{$group: {
_id: null,
"suma": {$sum: "$song.length" }
}}
])