如何按mongo中的数组值分组?

时间:2017-10-23 09:55:45

标签: arrays mongodb grouping

请帮帮我。 我想计算集合中所有文档的值的数量。 如何解决我的问题才能得到这个结果?

我的文件:

'title' => 'Televisor # 1',
'networks'    => [12, 3],
'resolutions' => [7],
'interfaces'  => [13, 9],

'title' => 'Televisor # 2',
'networks'    => [12],
'resolutions' => [9],
'interfaces'  => [13, 9, 24],

我想得到这个结果

networks
 value 12, count 2
 value 3, count 1

resolutions
 value 7, count 1
 value 9, count 1

interfaces
 value 13, count 2
 value 9, count 2
 value 24, count 1

3 个答案:

答案 0 :(得分:1)

您可以使用单个聚合查询执行所需操作:

db.yourDb.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $project: {
                "_id": 0,
                "title": 0
            }
        },

        // Stage 2
        {
            $project: {
                "parts": [
                    { "value": "$networks" },
                    { "value": "$resolutions" },
                    { "value": "$interfaces" }
                ]
            }
        },

        // Stage 3
        {
            $unwind: {
                "path": "$parts",
                "includeArrayIndex": "partIndex"
            }
        },

        // Stage 4
        {
            $project: {
                "value": "$parts.value",
                "partName": {
                    "$cond": {
                        "if": { "$eq": [ "$partIndex", 0 ] },
                        "then": "networks",
                        "else": {
                            "$cond": {
                                "if": { "$eq": [ "$partIndex", 1 ] },
                                "then": "resolutions",
                                "else": "interfaces"
                            }
                        }
                    }
                }
            }
        },

        // Stage 5
        {
            $unwind: {
                "path": "$value"
            }
        },

        // Stage 6
        {
            $group: {
                "_id": {
                    "partName": "$partName",
                    "value": "$value"
                },
                "count": { "$sum": 1 }
            }
        },

        // Stage 7
        {
            $project: {
                "_id": 0,
                "partName": "$_id.partName",
                "stats": {
                    "value": "$_id.value",
                    "count": "$count"
                }
            }
        },

        // Stage 8
        {
            $group: {
                "_id": "$partName",
                "stats": { "$push": "$stats" }
            }
        },

    ]
);

运行此聚合的结果是:

{ 
    "_id" : "resolutions", 
    "stats" : [
        {
            "value" : 7.0, 
            "count" : 1.0
        }, 
        {
            "value" : 9.0, 
            "count" : 1.0
        }
    ]
}
{ 
    "_id" : "networks", 
    "stats" : [
        {
            "value" : 12.0, 
            "count" : 2.0
        }, 
        {
            "value" : 3.0, 
            "count" : 1.0
        }
    ]
}
{ 
    "_id" : "interfaces", 
    "stats" : [
        {
            "value" : 24.0, 
            "count" : 1.0
        }, 
        {
            "value" : 9.0, 
            "count" : 2.0
        }, 
        {
            "value" : 13.0, 
            "count" : 2.0
        }
    ]
}

我很确定它可以进行一些优化,但无论如何你应该得到关键的想法。

答案 1 :(得分:0)

使用简单的查找查询和forEach循环可能会解决您的问题。如果你可以使用没有聚合的mongo查询,那么请试试这个:

var result = {network: [], resolution: [], interface: []};

db.new_collection.find({}).forEach( function(myDoc) {

  result['network'] = result['network'].concat(myDoc.networks);

  result['resolution'] = result['resolution'].concat(myDoc.resolutions);

  result['interface'] = result['interface'].concat(myDoc.interfaces);

})

printjson(result);

进入'结果'对象您将获得所有收集的数组值,然后您可以根据要求对其进行排序。

答案 2 :(得分:0)

除了执行三个不同的查询之外,我没有看到任何其他方式。

db.mycol.aggregate([ {$unwind:"$network"}, {$group:{_id: "$network", count:{$sum:1}}} ])

db.mycol.aggregate([ {$unwind:"$interfaces"}, {$group:{_id: "$interfaces", count:{$sum:1}}} ])

db.mycol.aggregate([ {$unwind:"$resolutions"}, {$group:{_id: "$resolutions", count:{$sum:1}}} ])

如果您正在使用node.js,则可以使用async以串行或并行方式触发这些命令,并获得组合输出。