MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Résoudre le tableau MongoDB DBRef à l'aide de Mongo Native Query et travailler sur les documents résolus

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.