Datastrukturen her er ikke en god implementering, der er masser af problemer med hvordan dette er opbygget og det er fuldstændig uegnet til aggregering. Hovedproblemerne her er:
-
Din struktur bruger faktisk ingen arrays, lige nu gør den ikke
-
Alle de specifikke nøglenavne er et reelt problem, og dette kan undgås.
Som sådan er den eneste måde at krydse denne slags struktur på at bruge JavaScript med mapReduce.
Definering af en mapper:
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]
);
}
}
};
Så det, dette gør, er at cykle gennem hver af versionsposterne og derefter også gennem alt om indhold. Nøglen udsendes for hver af de indholdsnøgler, du ønsker, samt af "chairtype"-tasten. Og værdien er den matchende værdi.
Og så en reduktion:
var reducer = function (key,values) {
return ( Array.sum( values ) != 0 )
? Array.sum( values ) / values.length : 0;
};
Hvilket blot er en simpel måde at producere et gennemsnit på fra alle de værdier, der kommer ind for kortlæggeren med den samme nøgle.
Så selvom det burde fungere godt, er det, du bør gøre, at ændre din struktur. Så faktisk hvis du havde noget som dette:
{
"_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 }
]
}
Eller generelt mere eller mindre i den form, bliver aggregeringsoperationen meget enkel:
db.collection.aggregate([
{ "$unwind": "$content" },
{ "$group": {
"_id": {
"chairtype": "$chairtype",
"key": "$content.key"
},
"average": { "$avg": "$content.value" }
}}
])
Eller hvilken som helst anden variation af dette, der kræves, men nu er det gjort muligt ved at ændre strukturen.
Så uden at dokumentet er struktureret anderledes, skal du bruge mapReduce til at gøre dette.