首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB -聚合多个行

MongoDB -聚合多个行
EN

Stack Overflow用户
提问于 2015-09-17 10:33:35
回答 1查看 65关注 0票数 2

假设以下聚合查询:

代码语言:javascript
复制
Machine.aggregate(  [ { $match : {  $and: [  {"idc": req.query.idc }, {"customer":req.query.customer} ] } } ,{"$group":{_id: {"cluster":"$cluster","idc":"$idc","type":"$type"},"SumCores":{"$sum":"$cores"},"SumMemory": { "$sum":"$memory" }}}, { $sort : { idc : -1, cluster: 1 } } ]);

返回:

代码语言:javascript
复制
[
{
    "_id": {
        "cluster": 1,
        "idc": "LH5",
        "type": "Virtual"
    },
    "SumCores": 112,
    "SumMemory": 384
},
{
    "_id": {
        "cluster": 1,
        "idc": "LH5",
        "type": "Physical"
    },
    "SumCores": 192,
    "SumMemory": 768
},
{
    "_id": {
        "cluster": 1,
        "idc": "LH8",
        "type": "Virtual"
    },
    "SumCores": 232,
    "SumMemory": 469
},
{
    "_id": {
        "cluster": 1,
        "idc": "LH8",
        "type": "Physical"
    },
    "SumCores": 256,
    "SumMemory": 1024
}
]

是否有一种方法可以更改聚合以检索所需的输出:

代码语言:javascript
复制
[
   {
    "_id": {
        "cluster": 1,
        "idc": "LH5"
    },
    "Virtual": {
        "SumCores": 112,
        "SumMemory": 384
    },
    "Physical": {
        "SumCores": 192,
        "SumMemory": 768
    }
},
{
    "_id": {
        "cluster": 1,
        "idc": "LH8"
    },
    "Virtual": {
        "SumCores": 232,
        "SumMemory": 469
    },
    "Physical": {
        "idc": "LH8",
        "type": "Physical"
    }
}
]

假设:

  • 每个IDC/集群总是有一个物理的和虚拟的“对”

我很高兴收到以下解决办法:

( a)更改聚合查询b)接收现有数据并通过库和/或算法将其转换为这种格式

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-17 12:13:48

您已经在查询中做了所有正确的事情,因为您需要在您所拥有的级别上进行$group,以获得正确的和。剩下的唯一的办法就是把一切都集中起来。

就我个人而言,我会把数组中的“对”作为最后的输出:

代码语言:javascript
复制
Machine.aggregate([ 
    { "$match": { 
        "idc": req.query.idc, "customer": req.query.customer}
    } ,
    { "$group": { 
        "_id": {
            "cluster": "$cluster",
            "idc":"$idc",
            "type": "$type"
        },
        "SumCores": { "$sum":"$cores" },
        "SumMemory": { "$sum":"$memory" }
    }},
    { "$group": {
        "_id": {
            "cluster": "$_id.cluster",
            "idc": "$_id.idc"
        },
        "data": {
            "$push": {
                "type": "$_id.type",
                "SumCores": "$SumCores",
                "SumMemory": "$SumMemory"
            }
        }
    }},
    { "$sort" : { "_id.idc": -1, "_id.cluster": 1 } }
]);

这会让你:

代码语言:javascript
复制
{
        "_id" : {
                "cluster" : 1,
                "idc" : "LH8"
        },
        "data" : [
                {
                        "type" : "Virtual",
                        "SumCores" : 232,
                        "SumMemory" : 469
                },
                {
                        "type" : "Physical",
                        "SumCores" : 256,
                        "SumMemory" : 1024
                }
        ]
}
{
        "_id" : {
                "cluster" : 1,
                "idc" : "LH5"
        },
        "data" : [
                {
                        "type" : "Virtual",
                        "SumCores" : 112,
                        "SumMemory" : 384
                },
                {
                        "type" : "Physical",
                        "SumCores" : 192,
                        "SumMemory" : 768
                }
        ]
}

但是,如果确实需要,则可以从数组中筛选出匹配的元素,并将它们放入它们自己的属性中:

代码语言:javascript
复制
Machine.aggregate([ 
    { "$match": { 
        "idc": req.query.idc, "customer": req.query.customer}
    } ,
    { "$group": { 
        "_id": {
            "cluster": "$cluster",
            "idc":"$idc",
            "type": "$type"
        },
        "SumCores": { "$sum":"$cores" },
        "SumMemory": { "$sum":"$memory" }
    }},
    { "$group": {
        "_id": {
            "cluster": "$_id.cluster",
            "idc": "$_id.idc"
        },
        "data": {
            "$push": {
                "type": "$_id.type",
                "SumCores": "$SumCores",
                "SumMemory": "$SumMemory"
            }
        }
    }},
    { "$project": {
        "Physical": {
            "$setDifference": [
                { "$map": {
                    "input": "$data",
                    "as": "el",
                    "in": {
                        "$cond": [
                            { "$eq": [ "$$el.type", "Physical" ] },
                            {
                                "SumCores": "$$el.SumCores",
                                "SumMemory": "$$el.SumMemory"
                            },
                            false
                        ]
                    }
                }},
                [false]
            ]
        },
        "Virtual": {
            "$setDifference": [
                { "$map": {
                    "input": "$data",
                    "as": "el",
                    "in": {
                        "$cond": [
                            { "$eq": [ "$$el.type", "Virtual" ] },
                            {
                                "SumCores": "$$el.SumCores",
                                "SumMemory": "$$el.SumMemory"
                            },
                            false
                        ]
                    }
                }},
                [false]
            ]
        }
    }},
    { "$unwind": "$Physical" },
    { "$unwind": "$Virtual"},
    { "$sort" : { "_id.idc": -1, "_id.cluster": 1 } }
]);

这给了你你的结果

代码语言:javascript
复制
{
        "_id" : {
                "cluster" : 1,
                "idc" : "LH8"
        },
        "Physical" : {
                "SumCores" : 256,
                "SumMemory" : 1024
        },
        "Virtual" : {
                "SumCores" : 232,
                "SumMemory" : 469
        }
}
{
        "_id" : {
                "cluster" : 1,
                "idc" : "LH5"
        },
        "Physical" : {
                "SumCores" : 192,
                "SumMemory" : 768
        },
        "Virtual" : {
                "SumCores" : 112,
                "SumMemory" : 384
        }
}

但是第一种方法只是给出相同的基本数据,而不需要对结果进行额外的传递。

无论如何,如果你真的必须要有这种数据格式的话,它实际上仅仅是将所有的数据整合在一起的多一个$group,然后是可选的阶段。但是我会亲自处理需要处理的代码中的“对”的任何访问。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32628218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档