繁体   English   中英

如何在mongodb中嵌套总和

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM