Ja inderdaad, het veld "territories"
heeft een array van databasereferenties
en not the actual documents
. DBRefs
zijn objecten die contain information with which we can locate the actual documents
.
In het bovenstaande voorbeeld kun je dit duidelijk zien, vuur de onderstaande mongo-query af:
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
het zal het DBref-object afdrukken in plaats van het document zelf:
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
dus, '$sum': '$territories.name'
,'$sum': '$territories.area'
zou u '0' tonen omdat er geen velden zijn zoals name
of area
.
U moet deze verwijzing naar een document dus oplossen voordat u iets doet als $territories.name
Om te bereiken wat je wilt, kun je gebruik maken van de map()
functie, aangezien aggregatie noch Map-reduce subquery's ondersteunt, en u al een op zichzelf staande map
hebt document, met verwijzingen naar zijn territories
.
Stappen om te bereiken:
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.
Mongo shell-script:
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
functies mogen en kunnen niet worden gebruikt om DBRefs
op te lossen aan de serverzijde. Zie wat de documentatie te zeggen heeft:
Bovendien, een reduce
functie, zelfs als deze wordt gebruikt (die toch nooit kan werken) zal nooit worden aangeroepen voor uw probleem, aangezien een groep w.r.t "fileName"
of "ObjectId"
zou altijd maar één document in uw dataset hebben.