在MongoDB中计算不同的值

时间:2015-09-28 14:01:37

标签: mongodb aggregation-framework

我尝试在MongoDB中计算不同的值,但我没有得到我期望的结果。

以下是数据样本:

{
        "_id" : ObjectId("55d354b0d5cec8aad571b8fe"),
        "version" : "0.4",
        "scan-time" : {
                "start" : 1439913109,
                "end" : 1439913136
        },
        "services" : [
                {
                        "service-type" : "SV1",
                        "service-version" : "V1",
                        "location" : {
                                "ipv4-address" : "192.168.1.1",
                                "protocol" : "tcp"
                        },
                        "classification-method" : "probed"
                },
                {
                        "service-type" : "SV1",
                        "service-version" : "V2",
                        "location" : {
                                "ipv4-address" : "192.168.1.2",
                                "protocol" : "tcp"
                        },
                        "classification-method" : "probed"
                },
                {
                        "location" : {
                                "ipv4-address" : "192.168.1.3",
                                "protocol" : "tcp"
                        },
                        "classification-method" : "probed",
                        "service-type" : "SV1",
                        "service-version" : "V3"
                },
                {
                        "service-type" : "SV2",
                        "service-version" : null,
                        "location" : {
                                "ipv4-address" : "192.168.1.4",
                                "protocol" : "tcp"
                        },
                        "classification-method" : "probed"
                }
        ]
}

我可以使用此查询列出所有不同的值:

db.collection.distinct("services.service-type")

但是,我还需要一个计数。我尝试过这个,但它没有给出我想要的结果:

db.collection.aggregate(
    [
       {
         $group : {
            _id : "$services.service-type",
            count: { $sum: 1 }
         }
       }
    ]
)

我需要看到这个:

SV1: 3
SV2: 1

MongoDB版本:

> db.version()
3.0.5

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

要在不同的查询中使用嵌套服务数组,您需要使用$unwind

来展开$ services

以下查询将输出不同的计数:

db.collection.aggregate([     
    { $unwind: "$services" },
    {
      $group : {
         _id : { "services-service-type": "$services.service-type" },
         count: { $sum: 1 }
      }
    }
])

输出:

{
    "result" : [ 
        {
            "_id" : {
                "services-service-type" : "SV2"
            },
            "count" : 1
        }, 
        {
            "_id" : {
                "services-service-type" : "SV1"
            },
            "count" : 3
        }
    ],
    "ok" : 1
}

答案 1 :(得分:1)

首先,您需要$project您的文档并返回所有service-type 的数组,以减少您需要在管道中处理的文档的大小,因为$unwind复制了每个文档在集合。为此,请使用$map运算符。然后你可以$unwind返回数组,最后在你的组项目中使用$sum累加器来返回不同service-type的计数

db.collection.aggregate([
    { "$project": { 
        "services": { 
            "$map": { 
                "input": "$services", 
                "as": "s", 
                "in": "$$s.service-type" 
            }
        }
    }}, 
    { "$unwind": "$services" },
    { "$group": { 
        "_id": "$services",  
        "count": { "$sum": 1 } 
    }}
])

返回:

{ "_id" : "SV2", "count" : 1 }
{ "_id" : "SV1", "count" : 3 }