MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Auflösen des MongoDB DBRef-Arrays mit Mongo Native Query und Bearbeiten der aufgelösten Dokumente

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.