获取MongoDB聚合$ group的百分比

use*_*562 14 mongodb aggregation-framework

我想从MongoDB聚合中的组管道中获取百分比.

我的数据:

{
    _id : 1,
    name : 'hello',
    type : 'big'
},
{
    _id : 2,
    name : 'bonjour',
    type : 'big'
},
{
    _id : 3,
    name : 'hi',
    type : 'short'
},
{
    _id : 4,
    name : 'salut',
    type : 'short'
},
{
    _id : 5,
    name : 'ola',
    type : 'short'
}
Run Code Online (Sandbox Code Playgroud)

我的请求组按类型和计数:

[{
    $group : {
        _id : {
            type : '$type'
        },
        "count" : {
            "$sum" : 1
        }
    }
}]
Run Code Online (Sandbox Code Playgroud)

结果:

[
    {
        _id {
            type : 'big',
        },
        count : 2
    },
    {
        _id {
            type : 'short',
        },
        count : 3
    }
]
Run Code Online (Sandbox Code Playgroud)

但我想要计算AND百分比,就像那样:

[
    {
        _id {
            type : 'big',
        },
        count: 2,
        percentage: 40%
    },
    {
        _id {
            type : 'short',
        },
        count: 3,
        percentage: 60%
    }
]
Run Code Online (Sandbox Code Playgroud)

但我不知道该怎么做.我尝试了$divide其他的东西,但没有成功.请你帮助我好吗?

sty*_*ane 9

好吧,percentage如果值包含,我认为应该是字符串%

首先得到你需要count的文件数量.

var nums = db.collection.count();

db.collection.aggregate(
    [
        { "$group": { "_id": {"type":  "$type"}, "count": { "$sum": 1 }}},    
        { "$project": { 
            "count": 1, 
            "percentage": { 
                "$concat": [ { "$substr": [ { "$multiply": [ { "$divide": [ "$count", {"$literal": nums }] }, 100 ] }, 0,2 ] }, "", "%" ]}
            }
        }
    ]
)
Run Code Online (Sandbox Code Playgroud)

结果

{ "_id" : { "type" : "short" }, "count" : 3, "percentage" : "60%" }
{ "_id" : { "type" : "big" }, "count" : 2, "percentage" : "40%" }
Run Code Online (Sandbox Code Playgroud)


Yog*_*esh 5

首先使用count方法查找集合中的文档总数,然后使用该计数变量进行percentage聚合计算,如下所示:

var totalDocument = db.collectionName.count() //count total doc.
Run Code Online (Sandbox Code Playgroud)

用于totalDocument聚合,如下所示:

db.collectionName.aggregate({"$group":{"_id":{"type":"$type"},"count":{"$sum":1}}},
                            {"$project":{"count":1,"percentage":{"$multiply":[{"$divide":[100,totalDocument]},"$count"]}}})
Run Code Online (Sandbox Code Playgroud)

编辑

如果您需要在单个aggregation查询中进行此操作,则unwind可以在聚合中使用unwind,但使用它会Cartesian problem在聚合查询下方创建检查:

db.collectionName.aggregate({"$group":{"_id":null,"count":{"$sum":1},"data":{"$push":"$$ROOT"}}},
                            {"$unwind":"$data"},
                             {"$group":{"_id":{"type":"$data.type"},"count":{"$sum":1},
                                       "total":{"$first":"$count"}}},
                             {"$project":{"count":1,"percentage":{"$multiply":[{"$divide":[100,"$total"]},"$count"]}}}
                            ).pretty()
Run Code Online (Sandbox Code Playgroud)

我建议先找出总数,并根据第一次查询将其用于聚合。