2017-01-19 4 views
0

У меня есть простой документ с одним полем как пара ключ-значение. Я хочу просто выполнить групповую операцию в Агрегации над этими ключами и добавить их значения. Но ключи в паре не фиксированы и могут быть любыми.MongoDB: Операция Aggregation Group над динамической парой ключ-значение

Вот пример документа.

{ 
    _id: 349587843, 
    matchPair: { 
     3 : 21, 
     9 : 4, 
     7 : 32 
    } 
}, 
{ 
    _id: 349587478, 
    matchPair: { 
     7 : 11, 
     54 : 32, 
     9 : 7, 
     2 : 19 
    } 
} 

И я хочу получить что-то вроде следующего.

{ 
    _id : 3, 
    count : 21 
}, 
{ 
    _id : 9, 
    count : 11 
}, 
{ 
    _id : 7, 
    count : 43 
}, 
{ 
    _id : 54, 
    count : 32 
}, 
{ 
    _id : 2, 
    count : 19 
} 

У меня есть следующий запрос в виду, и попытался использовать $unwind операцию, но она не работает, вероятно, потому, что «matchPair» не является массивом, и я не знаю, что указать на $sum операции.

db.MatchPairs.aggregate([ 
    { "$unwind" : "$matchPair" }, 
    { "$group" : { 
     _id: "$matchPair", 
     count : { $sum : $matchPair } 
    } } 
]); 

Я мог бы также попробовать Map-Reduce, но для этого тоже нужно emit() ключей и значений по имени.

Я уверен, что есть простое решение, но я не могу понять это.

+0

это невозможно с помощью структуры агрегации, если ваши клавиши являются динамическими, поэтому вам нужно перейти на mapReduce – felix

+0

Я вижу. Не могли бы вы рассказать мне, как я буду указывать ключи и значения в функции 'emit()'? –

+0

Пример уменьшения карты для аналогичной проблемы: http://stackoverflow.com/a/41634637/2965883 – ares

ответ

0

В документации MongoDB для $unwind:

деконструирует поле массива из входных документов для вывода документа для каждого элемента.

Таким образом, вы должны изменить вашу схему что-то вроде:

{ 
    "_id" : ObjectId("5880b57b039a3c89c1db145a"), 
    "matchPair" : [ 
     { 
      "_id" : "3", 
      "count" : 21 
     }, 
     { 
      "_id" : "9", 
      "count" : 4 
     }, 
     { 
      "_id" : "7", 
      "count" : 32 
     } 
    ] 
}, 
{ 
    "_id" : ObjectId("5880b58c039a3c89c1db145b"), 
    "matchPair" : [ 
     { 
      "_id" : "7", 
      "count" : 11 
     }, 
     { 
      "_id" : "54", 
      "count" : 32 
     }, 
     { 
      "_id" : "9", 
      "count" : 7 
     }, 
     { 
      "_id" : "2", 
      "count" : 19 
     } 
    ] 
} 

Затем делают:

db.MatchPairs.aggregate([ 
    { $unwind : "$matchPair" } 
]); 

вернется:

{ 
    "_id" : ObjectId("5880b57b039a3c89c1db145a"), 
    "matchPair" : { 
     "_id" : "3", 
     "count" : 21 
    } 
}, 
{ 
    "_id" : ObjectId("5880b57b039a3c89c1db145a"), 
    "matchPair" : { 
     "_id" : "9", 
     "count" : 4 
    } 
}, 
{ 
    "_id" : ObjectId("5880b57b039a3c89c1db145a"), 
    "matchPair" : { 
     "_id" : "7", 
     "count" : 32 
    } 
}, 
{ 
    "_id" : ObjectId("5880b58c039a3c89c1db145b"), 
    "matchPair" : { 
     "_id" : "7", 
     "count" : 11 
    } 
}, 
{ 
    "_id" : ObjectId("5880b58c039a3c89c1db145b"), 
    "matchPair" : { 
     "_id" : "54", 
     "count" : 32 
    } 
}, 
{ 
    "_id" : ObjectId("5880b58c039a3c89c1db145b"), 
    "matchPair" : { 
     "_id" : "9", 
     "count" : 7 
    } 
}, 
{ 
    "_id" : ObjectId("5880b58c039a3c89c1db145b"), 
    "matchPair" : { 
     "_id" : "2", 
     "count" : 19 
    } 
} 

Тогда вам просто нужно сделать вашей группировки.

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

  • Нет связанных вопросов^_^