2015-09-28 102 views
0

我有以下MongoDB聚合查詢,這些查詢由IDC,類型和集羣進行分組 - 這完美地工作。MongoDB - 複雜的分組查詢

我想額外將「環境」,組合在這個現有的分組中。請參閱下面的查詢,我現有的輸出,以及我想看到的內容(所需輸出)。

如果您有任何問題或希望看到源代碼(我認爲這不是必要的,因爲它會佔用問題的空間,請評論)。

感謝

示例源(約1000文件):

{ 
     "_id":"55d5dc40281077b6d8af1bfa", 
     "hostname":"1", 
     "domain":"domain", 
     "description":"VMWare ESXi 5", 
     "cluster":1, 
     "type":"Physical", 
     "os":"EXSi", 
     "idc":"AMS", 
     "environment":"DR", 
     "deviceclass":"host", 
     "cores":64, 
     "memory":256, 
     "clusters":0, 
     "customer":"MnS", 
     "mounts":[], 
     "roles":["ESX-HOST"], 
     "ipset":{"backnet":"1"}, 
     "frontnet":[], 
     "created":"2015-09-28T11:12:36.526Z" 
    } 

查詢:

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 } } 
]); 

這給了我下面的輸出:

{ 
    "_id" : { 
      "cluster" : 1, 
      "idc" : "LH5" 
    }, 
    "Physical" : { 
      "SumCores" : 192, 
      "SumMemory" : 768 
    }, 
    "Virtual" : { 
      "SumCores" : 112, 
      "SumMemory" : 384 
    } 
} 

我的期望輸出一世S:

[ 
{ 
    "_id": { 
     "cluster": 1, 
     "idc": "LH8" 
    }, 
    "Physical": [ 
     { 
      "environment": "DR", 
      "SumCores": 256, 
      "SumMemory": 1024 
     }, 
     { 
      "environment": "PROD", 
      "SumCores": 256, 
      "SumMemory": 1024 
     } 
    ], 
    "Virtual": [ 
     { 
      "environment": "DR", 
      "SumCores": 232, 
      "SumMemory": 469 
     }, 
     { 
      "environment": "PROD", 
      "SumCores": 232, 
      "SumMemory": 469 
     } 
    ] 
} 
] 

從本質上講,我想小組基於對環境的款項

+0

很不錯的,你要告訴我們什麼你期望作爲輸出。不幸的是,您的問題不會告訴任何人「源」數據的外觀。因此,任何人都無法就如何達到預期結果提供建議。如果你希望在這個問題上得到一些幫助,我建議在「源代碼」中增加一個數據樣本的樣本。 –

+0

@BlakesSeven - 已添加源代碼示例 - 謝謝 – CMS

回答

1

非常喜歡在你的初始查詢(actually written by myself),你真正需要做的是在這一領域的細節添加到$group初始_id再進行,通過到隨後的數組項:

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

但你也「確實」應該使用查詢˚F ORM我建議你在第一個地方做,因爲很顯然,所有你想要做的就是在模板diplay這個和循環數組的內容應該是很簡單的:

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