Oui effectivement, le champ "territories"
a un tableau de références de base de données
et not the actual documents
. DBRefs
sont des objets qui contain information with which we can locate the actual documents
.
Dans l'exemple ci-dessus, vous pouvez clairement le voir, lancez la requête mongo ci-dessous :
db.maps.find({"_id":ObjectId("542489232436657966204394")}).forEach(function(do
c){print(doc.territories[0]);})
il imprimera l'objet DBRef plutôt que le document lui-même :
o/p: DBRef("territories", ObjectId("5424892224366579662042e9"))
donc, '$sum': '$territories.name'
,'$sum': '$territories.area'
vous montrerait '0' car il n'y a pas de champs tels que name
ou area
.
Vous devez donc résoudre cette référence à un document avant de faire quelque chose comme $territories.name
Pour obtenir ce que vous voulez, vous pouvez utiliser le map()
fonction, puisque l'agrégation ni Map-reduce ne prennent en charge les sous-requêtes, et vous avez déjà une map
autonome document, avec des références à ses territories
.
Étapes à suivre :
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 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
les fonctions ne doivent pas et ne peuvent pas être utilisées pour résoudre DBRefs
du côté serveur.Voir ce que la documentation a à dire :
De plus, une reduce
la fonction même si elle est utilisée (qui ne peut jamais fonctionner de toute façon) ne sera jamais appelée pour votre problème, car un groupe w.r.t "fileName"
ou "ObjectId"
aurait toujours un seul document, dans votre jeu de données.