Ja faktisk, feltet "territories"
har en række databasereferencer
og not the actual documents
. DBRefs
er objekter, der contain information with which we can locate the actual documents
.
I ovenstående eksempel kan du tydeligt se dette, affyr nedenstående mongo-forespørgsel:
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
det vil udskrive DBRef-objektet i stedet for selve dokumentet:
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
så, '$sum': '$territories.name'
,'$sum': '$territories.area'
ville vise dig '0', da der ikke er nogen felter såsom name
eller area
.
Så du skal løse denne reference til et dokument, før du gør noget som $territories.name
For at opnå det, du ønsker, kan du gøre brug af map()
funktion, da aggregering eller Map-reducer understøtter underforespørgsler, og du allerede har et selvstændigt map
dokument med referencer til dets territories
.
Trin for at opnå:
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
funktioner skal ikke være og kan ikke bruges til at løse DBRefs
på serversiden. Se, hvad dokumentationen har at sige:
Desuden en reduce
funktion, selvom den bruges (som aldrig kan fungere alligevel) vil aldrig blive kaldt for dit problem, da en gruppe w.r.t "fileName"
eller "ObjectId"
ville altid kun have ét dokument i dit datasæt.