2015-09-17 2 views
2

Пусть следующий агрегирования запрос:MongoDB - Совокупный Muliple строка

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

возвращающее:

[ 
{ 
    "_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 
} 
] 

Есть ли способ изменить агрегацию для получения этого желаемого выхода:

[ 
    { 
    "_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/Cluster

Я рад получить решения, которые:

а) изменение агрегации запроса б) получающего существующий данные и изменить его в этот формат в качестве библиотеки и/или алгоритма

ответ

1

вы делаете все правильные вещи в запросе уже, как вам нужно $group на уровне, который у вас есть, чтобы получить правильные суммы. Остается только собрать все это вместе.

Лично я бы придерживаться с «парой» в массиве как окончательный вывод:

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

который даст вам:

{ 
     "_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 
       } 
     ] 
} 

Но если вам действительно необходимо, то вы можете фильтровать вывести согласованные элементы из массива и поставить их в свои собственные свойства:

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" : "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, чтобы собрать все это вместе, а затем необязательные этапы, если вы действительно должны иметь такой формат данных. Но я бы лично обработал любой доступ к «паре» в коде, который должен иметь дело с ним.

+0

Это именно то, что мне было нужно - я тоже пошел с вашим предложением :) – CMS

+0

Просто быстрая записка - как я могу получить доступ к «Физическим» общим ядрам в вашем методе? – CMS

+0

@CMS Аналогичным образом, по существу, отфильтровывает требуемый элемент для соответствия массиву. Или в зависимости от того, как данные использовались (например, для отображения), я просто перебирал разделы для создания списка для каждого типа. Зависит от использования. –

Смежные вопросы