Sì, infatti, il campo "territories"
ha una serie di riferimenti al database
e not the actual documents
. DBRefs
sono oggetti che contain information with which we can locate the actual documents
.
Nell'esempio sopra, puoi vederlo chiaramente, attiva la seguente query mongo:
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
stamperà l'oggetto DBRef anziché il documento stesso:
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
quindi, '$sum': '$territories.name'
,'$sum': '$territories.area'
ti mostrerebbe '0' poiché non ci sono campi come name
o area
.
Quindi devi risolvere questo riferimento a un documento prima di fare qualcosa come $territories.name
Per ottenere ciò che desideri, puoi utilizzare la map()
funzione, poiché l'aggregazione né la riduzione della mappa supportano le query secondarie e hai già una map
autonoma documento, con riferimenti ai suoi territories
.
Passi da raggiungere:
a) get each map
b) resolve the `DBRef`.
c) calculate the total area, and the number of territories.
d) make and return the desired structure.
Script della shell Mongo:
db.maps.find().map(function(doc) {
var territory_refs = doc.territories.map(function(terr_ref) {
refName = terr_ref.$ref;
return terr_ref.$id;
});
var areaSum = 0;
db.refName.find({
"_id" : {
$in : territory_refs
}
}).forEach(function(i) {
areaSum += i.area;
});
return {
"id" : doc.fileName,
"noOfTerritories" : territory_refs.length,
"areaSum" : areaSum
};
})
o/p:
[
{
"id" : "importFile1.json",
"noOfTerritories" : 2,
"areaSum" : 1906609
},
{
"id" : "importFile2.json",
"noOfTerritories" : 1,
"areaSum" : 0
}
]
Map-Reduce
le funzioni non devono essere e non possono essere utilizzate per risolvere DBRefs
sul lato server. Guarda cosa dice la documentazione:
Inoltre, una reduce
la funzione anche se utilizzata (che comunque non può mai funzionare) non verrà mai chiamata per il tuo problema, poiché un gruppo w.r.t "fileName"
o "ObjectId"
avrebbe sempre un solo documento, nel tuo set di dati.