De datastructuur hier is geen goede implementatie, er zijn veel problemen met hoe dit is gestructureerd en het is volledig ongeschikt voor aggregatie. De belangrijkste problemen hier zijn:
-
Uw structuur gebruikt eigenlijk geen arrays, op dit moment niet
-
Alle specifieke sleutelnamen vormen een echt probleem, en dit kan worden vermeden.
Als zodanig is de enige manier om dit soort structuur te doorkruisen het gebruik van JavaScript met mapReduce.
Een mapper definiëren:
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]
);
}
}
};
Dus wat dit doet, is door elk van de versies-items fietsen en vervolgens ook door alles over inhoud. De sleutel wordt verzonden voor elk van de gewenste inhoudssleutels, evenals door de "stoeltype" -sleutel. En de waarde is die overeenkomende waarde.
En dan een verloopstuk:
var reducer = function (key,values) {
return ( Array.sum( values ) != 0 )
? Array.sum( values ) / values.length : 0;
};
Dat is slechts een eenvoudige manier om een gemiddelde te maken van alle waarden die binnenkomen voor de mapper met dezelfde sleutel.
Dus hoewel dat goed zou moeten werken, zou je je structuur moeten veranderen. Dus eigenlijk als je zoiets als dit had:
{
"_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 }
]
}
Of over het algemeen min of meer in die vorm, de aggregatiebewerking wordt heel eenvoudig:
db.collection.aggregate([
{ "$unwind": "$content" },
{ "$group": {
"_id": {
"chairtype": "$chairtype",
"key": "$content.key"
},
"average": { "$avg": "$content.value" }
}}
])
Of welke andere variatie hiervan ook nodig is, maar nu wordt het mogelijk gemaakt door de structuur te veranderen.
Dus zonder dat het document anders is gestructureerd, moet je hiervoor mapReduce gebruiken.