Ja, das Feld "territories"
hat ein Array von Datenbankreferenzen
und not the actual documents
. DBRefs
sind Objekte, die contain information with which we can locate the actual documents
.
Im obigen Beispiel können Sie dies deutlich sehen, lösen Sie die folgende Mongo-Abfrage aus:
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
es druckt das DBRef-Objekt statt des Dokuments selbst:
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
also '$sum': '$territories.name'
,'$sum': '$territories.area'
würde Ihnen '0' zeigen, da es keine Felder wie name
gibt oder area
.
Daher müssen Sie diesen Verweis auf ein Dokument auflösen, bevor Sie etwas wie $territories.name
tun
Um das zu erreichen, was Sie wollen, können Sie map()
verwenden Funktion, da sowohl Aggregation als auch Map-Reduce Unterabfragen unterstützen, und Sie haben bereits eine in sich geschlossene map
Dokument, mit Verweisen auf seine territories
.
Zu erreichende Schritte:
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-Skript:
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
Funktionen sollten und können nicht verwendet werden, um DBRefs
aufzulösen auf der Serverseite. Sehen Sie, was die Dokumentation zu sagen hat:
Außerdem ein reduce
Funktion, selbst wenn sie verwendet wird (was sowieso nie funktionieren kann), wird für Ihr Problem niemals aufgerufen, da eine Gruppe w.r.t "fileName"
oder "ObjectId"
immer nur ein Dokument in Ihrem Datensatz haben.