如何使用Mongdb通过选定属性(嵌套)对对象数进行计数

时间:2019-11-29 06:04:31

标签: mongodb mongodb-query aggregation-framework

我有一个集合,其中的文档采用这样的结构。

{
    "_id" : ObjectId("5d6db92e8e935c407f00f39c"),
    "id" : "1",
    "email" : "admin@test.com",
    "orgs" : [ 
        {
            "org_id" : "1",
            "org_name" : "Lenovo",
            "role" : "tenantadmin",
            "primary_locale" : null,
            "name" : "admin"
        }
    ]
}

我需要获取可用的 admin 角色的数量以及其他角色(任何其他tenantadmin,admin,user)的数量。这样就可以得到类似

的结果
{admin:10, others:20}

这是我尝试过的代码。

db.getCollection('users').aggregate([{'$unwind': '$orgs'},{ '$group': { '_id': "$orgs.role",'count': {'$sum': 1}}}])

这给了我所有角色类型的计数

{
    "_id" : "user",
    "count" : 3.0
}
{
    "_id" : "tenantadmin",
    "count" : 2.0
}
{
    "_id" : "admin",
    "count" : 5.0
}

如何获得像{admin:10, others:20}这样的输出?。

2 个答案:

答案 0 :(得分:2)

您可以使用$cond来定义分组密钥:

db.getCollection('users').aggregate([
    { '$unwind': '$orgs' },
    { '$group': { '_id': { $cond: [ { $eq: [ "$orgs.role", "admin" ] }, "$orgs.role", "other" ] },'count': {'$sum': 1}}}
    ]
)

Mongo Playground

编辑:要把分组_id作为结果的键,您可以运行另一个$group,然后运行$replaceRoot$arrayToObject

db.getCollection('users').aggregate([
    { '$unwind': '$orgs' },
    { '$group': { '_id': { $cond: [ { $eq: [ "$orgs.role", "admin" ] }, "$orgs.role", "other" ] },'count': {'$sum': 1}}},
    { '$group': { '_id': null, root: { $push: { k: '$_id', v: '$count' } } } },
    { '$replaceRoot': { newRoot: { $arrayToObject: '$root' } } }
    ]
)

Mongo Playground

答案 1 :(得分:1)

请尝试以下操作:

db.collection.aggregate([
        {
            "$addFields": {
                "other": {
                    "$size": { 
                        "$filter": {
                            "input": "$orgs",
                            "as": "el",
                            "cond": { "$ne": [ "$$el.role", "admin" ] }
                        }
                    }
                },
                "admin": {
                    "$size": { 
                        "$filter": {
                            "input": "$orgs",
                            "as": "el",
                            "cond": { "$eq": [ "$$el.role", "admin" ] }
                        }
                    }
                }
            }
        },
        {
            $project: {
                admin:1,
                other:1
            }
        }


    ])

结果将是:

{
    "_id" : ObjectId("5de0b60ec6794c1b2be95902"),
    "other" : 2,
    "admin" : 1
}