Има няколко различни подхода, които можете да използвате тук:
-
Използвайте map/reduce:не правете това. В момента би било много по-бързо да стартирате рамката за агрегиране 3 пъти, отколкото да използвате функция за намаляване на картата за този случай на употреба.
-
Стартирайте агрегацията 3 пъти. Това не е оптимално, но ако нямате времеви ограничения, това е най-лесният вариант. Ако вашите агрегирания така или иначе отнемат <няколко секунди, тогава не бих се притеснявал за оптимизиране, докато не станат проблем.
-
Ето най-доброто решение, за което мога да се сетя.
$group
оператор ви позволява да създадете_id
на множество полета. напр.{"_id":{"a":"$key1", "b":"$key2", "c":"$key3"}}
. Това създава групиране за всички съществуващи комбинации от вашите различни ключове. Потенциално бихте могли да групирате ключовете си по този начин и след това ръчно да сумирате резултатите в клиента.
Нека поясня по-подробно. Да кажем, че имаме колекция от форми. Тези форми могат да имат цвят, размер и вид (квадрат, кръг и т.н.). Агрегиране на многоключов идентификатор може да изглежда така:
db.shapes.aggregate({$group:{_id:{"f1":"$f1", "f2":"$f2", "f3":"$f3"}, count:{"$sum":1}}})
и връщане:
"result" : [
{
"_id" : {
"f1" : "yellow",
"f2" : "medium",
"f3" : "triangle"
},
"count" : 4086
},
{
"_id" : {
"f1" : "red",
"f2" : "small",
"f3" : "triangle"
},
"count" : 4138
},
{
"_id" : {
"f1" : "red",
"f2" : "big",
"f3" : "square"
},
"count" : 4113
},
{
"_id" : {
"f1" : "yellow",
"f2" : "small",
"f3" : "triangle"
},
"count" : 4145
},
{
"_id" : {
"f1" : "red",
"f2" : "small",
"f3" : "square"
},
"count" : 4062
}
... и така нататък
След това ще обобщите резултатите от страна на клиента, върху драстично намален брой записи. Ако приемем, че броят на уникалните стойности за всеки ключ е достатъчно малък в сравнение с общия брой документи, можете да направите тази последна стъпка за нищожно време.