Структурата на данните тук не е добра реализация, има много проблеми с това как е структурирана и е напълно неподходяща за агрегиране. Основните проблеми тук са:
-
Вашата структура всъщност не използва никакви масиви, точно сега не използва
-
Всички конкретни имена на ключове са истински проблем и това може да бъде избегнато.
Като такъв, единственият начин за преминаване през този вид структура е използването на JavaScript с mapReduce.
Дефиниране на картограф:
var mapper = function () {
for ( var n in this.versions ) {
for ( var k in this.versions[n].content ) {
if (
( k != 'confirmed' ) ||
( k != 'visited' ) )
emit(
{
type: this.chairtype,
key: k
},
this.versions[n].content[k]
);
}
}
};
Така че това, което прави, е циклично преминаване през всеки от записите на версиите и след това също през всичко в съдържанието. Ключът се излъчва за всеки от ключовете за съдържание, които искате, както и от ключа "chairtype". И стойността е тази съответстваща стойност.
И след това редуктор:
var reducer = function (key,values) {
return ( Array.sum( values ) != 0 )
? Array.sum( values ) / values.length : 0;
};
Което е просто прост начин за създаване на средна стойност от всички стойности, постъпващи за картографа със същия ключ.
Така че докато това трябва да работи добре, това, което трябва да направите, е да промените структурата си. Всъщност, ако имате нещо подобно:
{
"_id": ObjectId("52b85dfa32b6249513f15897"),
"parent": "47de3176-bbc3-44e0-8063-8920ac56fdc8",
"type": "chair",
"chairtype": "E",
"content": [
{ "key": "atkswlntfd", "value": 0, "version": 0 },
{ "key": "auwbsjqzir", "value": 0, "version": 0 },
{ "key": "avqrnjzbgd", "value": 0, "version": 0 }
]
}
Или като цяло повече или по-малко в тази форма, операцията за агрегиране става много проста:
db.collection.aggregate([
{ "$unwind": "$content" },
{ "$group": {
"_id": {
"chairtype": "$chairtype",
"key": "$content.key"
},
"average": { "$avg": "$content.value" }
}}
])
Или какъвто и да е друг вариант на това, който се изисква, но сега е възможен чрез промяна на структурата.
Така че, без документът да е структуриран по различен начин, ще трябва да използвате mapReduce, за да направите това.