La struttura dei dati qui non è una buona implementazione, ci sono molti problemi con il modo in cui è strutturata ed è completamente inadatta all'aggregazione. I problemi principali qui sono:
-
La tua struttura in realtà non utilizza alcun array, in questo momento non lo fa
-
Tutti i nomi di chiavi specifici rappresentano un vero problema e questo può essere evitato.
In quanto tale, l'unico modo per attraversare questo tipo di struttura è usare JavaScript con mapReduce.
Definizione di un mappatore:
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]
);
}
}
};
Quindi ciò che sta facendo è scorrere ciascuna delle voci delle versioni e quindi anche tutto sul contenuto. La chiave viene emessa per ciascuna delle chiavi di contenuto desiderate, nonché dalla chiave "chairtype". E il valore è quel valore corrispondente.
E poi un riduttore:
var reducer = function (key,values) {
return ( Array.sum( values ) != 0 )
? Array.sum( values ) / values.length : 0;
};
Che è solo un modo semplice per produrre una media da tutti i valori che arrivano per il mapper con la stessa chiave.
Quindi, mentre dovrebbe funzionare bene, quello che dovresti fare è cambiare la tua struttura. Quindi in effetti se avessi qualcosa del genere:
{
"_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 }
]
}
O generalmente più o meno in quella forma, l'operazione di aggregazione diventa molto semplice:
db.collection.aggregate([
{ "$unwind": "$content" },
{ "$group": {
"_id": {
"chairtype": "$chairtype",
"key": "$content.key"
},
"average": { "$avg": "$content.value" }
}}
])
O qualsiasi altra variazione di questo sia richiesta, ma ora è possibile modificando la struttura.
Quindi, senza che il documento sia strutturato in modo diverso, dovrai utilizzare mapReduce per farlo.