Ja verkligen, fältet "territories"
har en mängd databasreferenser
och not the actual documents
. DBRefs
är objekt som contain information with which we can locate the actual documents
.
I exemplet ovan kan du tydligt se detta, avfyra mongo-frågan nedan:
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
det kommer att skriva ut DBRef-objektet snarare än själva dokumentet:
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
så, '$sum': '$territories.name'
,'$sum': '$territories.area'
skulle visa dig '0' eftersom det inte finns några fält såsom name
eller area
.
Så du måste lösa denna referens till ett dokument innan du gör något som $territories.name
För att uppnå det du vill kan du använda map()
funktion, eftersom aggregering eller Map-reduce stödjer underfrågor, och du redan har en fristående map
dokument, med referenser till dess territories
.
Steg för att uppnå:
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-skalskript:
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
funktioner ska inte användas och kan inte användas för att lösa DBRefs
på serversidan. Se vad dokumentationen har att säga:
Dessutom en reduce
funktion även om den används (som aldrig kan fungera ändå) kommer aldrig att anropas för ditt problem, eftersom en grupp w.r.t "fileName"
eller "ObjectId"
skulle alltid bara ha ett dokument i din datauppsättning.