MongoDB Projekt verschachtelte Felder

Mehvish Ashiq 12 Juli 2022
  1. Verschachtelte Felder des MongoDB-Projekts
  2. Verwenden Sie die $project Aggregationsstufe um verschachtelte Felder in MongoDB zu projizieren
  3. Verwenden Sie die Aggregationsstufe $unset um verschachtelte Felder ohne die angegebenen Felder in MongoDB zu erhalten
  4. Verwenden einer forEach()-Schleife zum Abrufen verschachtelter Felder in MongoDB
  5. Verwenden Sie die Methode mapReduce(), um verschachtelte Felder in MongoDB zu projizieren
MongoDB Projekt verschachtelte Felder

Heute lernen wir, wie man die Aggregationsstufen $project und $unset, die Schleife forEach() und die Methode mapReduce() verwendet, um verschachtelte Felder zu projizieren, während Daten in MongoDB abgefragt werden.

Verschachtelte Felder des MongoDB-Projekts

In MongoDB können wir alle Dokumente mit der Methode find() abrufen, aber was ist, wenn wir nur auf bestimmte verschachtelte Felder zugreifen möchten. Hier verwenden wir Projektion.

Wir können verschachtelte Felder auf verschiedene Weise projizieren. Hier lernen wir die folgenden Lösungen zum Projizieren verschachtelter Felder kennen.

  1. Verwenden Sie die Aggregationsstufe $project
  2. Verwenden Sie die Aggregationsstufe $unset
  3. Verwenden Sie die forEach()-Schleife
  4. Verwenden Sie die Funktion mapReduce()

Um die obigen Ansätze zu lernen, erstellen wir eine Sammlung namens nested, die ein Dokument enthält. Sie können auch die unten angegebene Abfrage verwenden, um sich mit uns in Verbindung zu setzen.

Beispielcode:

// MongoDB version 5.0.8

> db.nested.insertOne(
    {
        "name": {
            "first_name": "Mehvish",
            "last_name": "Ashiq",
         },
         "contact": {
            "phone":{"type": "manager", "number": "123456"},
            "email":{ "type": "office", "mail": "delfstack@example.com"}
         },
         "country_name" : "Australien",
         "posting_locations" : [
             {
                 "city_id" : 19398,
                 "city_name" : "Bondi Beach (Sydney)"
             },
             {
                  "city_id" : 31101,
                  "city_name" : "Rushcutters Bay (Sydney)"
             },
             {
                  "city_id" : 31022,
                  "city_name" : "Wolly Creek (Sydney)"
             }
          ],
          "regions" : {
              "region_id" : 796,
              "region_name" : "Australien: New South Wales (Sydney)"
          }
    }
);

Verwenden Sie db.nested.find().pretty(); auf der Mongo-Shell, um die eingefügten Daten anzuzeigen.

Verwenden Sie die $project Aggregationsstufe um verschachtelte Felder in MongoDB zu projizieren

Beispielcode:

// MongoDB version 5.0.8

> var current_location = "posting_locations";
> var project = {};
> project["id"] = "$"+current_location+".city_id";
> project["name"] = "$"+current_location+".city_name";
> project["regions"] = 1;

> var find = {};
> find[current_location] = {"$exists":true};

> db.nested.aggregate([
    { $match : find },
    { $project : project }
]).pretty()

AUSGANG:

{
        "_id" : ObjectId("62a96d397c7e3688aea26d0d"),
        "regions" : {
                "region_id" : 796,
                "region_name" : "Australien: New South Wales (Sydney)"
        },
        "id" : [
                19398,
                31101,
                31022
        ],
        "name" : [
                "Bondi Beach (Sydney)",
                "Rushcutters Bay (Sydney)",
                "Wolly Creek (Sydney)"
        ]
}

Hier speichern wir das Feld der ersten Ebene namens posting_locations in einer Variablen namens current_location.

Dann verwenden wir diese Variable, um auf city_id und city_name zuzugreifen und speichern sie im project-Objekt, während wir die Klammernotation verwenden, um Eigenschaften für das project-Objekt zu erstellen. Zusätzlich speichern wir das Feld regions in project["regions"].

Als nächstes haben wir ein weiteres Objekt namens find, das wir in der aggregate()-Methode verwenden, um die Dokumente abzugleichen. In der aggregate()-Methode verwenden wir die Stufe $match, um die Dokumente abzugleichen, und $project, um die Felder zu projizieren, egal ob verschachtelt oder auf der ersten Ebene.

Wir verwenden $project, um anzugeben, welche Felder wir in der Ausgabe anzeigen möchten. Wir können die folgende Lösung verwenden, wenn wir daran interessiert sind, die angegebenen verschachtelten Felder nur ohne Filterabfrage zu projizieren.

Beispielcode:

// MongoDB version 5.0.8

> var current_location = "posting_locations";
> db.nested.aggregate({
    $project: {
         "_id": 0,
         "city_id": "$" + current_location + ".city_id",
         "city_name": "$" + current_location + ".city_name",
         "regions": 1
    }
}).pretty();

AUSGANG:

{
        "regions" : {
                "region_id" : 796,
                "region_name" : "Australien: New South Wales (Sydney)"
        },
        "city_id" : [
                19398,
                31101,
                31022
        ],
        "city_name" : [
                "Bondi Beach (Sydney)",
                "Rushcutters Bay (Sydney)",
                "Wolly Creek (Sydney)"
        ]
}

Verwenden Sie die Aggregationsstufe $unset um verschachtelte Felder ohne die angegebenen Felder in MongoDB zu erhalten

Beispielcode:

// MongoDB version 5.0.8

> db.nested.aggregate({
        $unset: ["posting_locations.city_id", "contact", "regions", "name", "_id"]
}).pretty()

AUSGANG:

{
        "country_name" : "Australien",
        "posting_locations" : [
                {
                        "city_name" : "Bondi Beach (Sydney)"
                },
                {
                        "city_name": "Rushcutters Bay (Sydney)"
                },
                {
                        "city_name": "Wolly Creek (Sydney)"
                }
        ]
}

Hier verwenden wir den Operator $unset, der verwendet wird, um das angegebene Feld oder Array von Feldern zu löschen.

Denken Sie daran, dass wir die Punktnotation verwenden, um die eingebetteten Dokumente oder das Array von Dokumenten anzugeben. Der Operator $unset führt keine Operation aus, wenn das angegebene Feld nicht existiert.

Wenn wir $ verwenden, um die Elemente eines Arrays abzugleichen, ersetzt der Operator $unset übereinstimmende Elemente durch null, anstatt sie aus dem Array zu entfernen. Dieses Verhalten trägt dazu bei, die Elementpositionen und die Arraygröße konsistent zu halten.

Verwenden einer forEach()-Schleife zum Abrufen verschachtelter Felder in MongoDB

Beispielcode:

// MongoDB version 5.0.8

> var bulk = db.newcollection.initializeUnorderedBulkOp(),
   counter = 0;

> db.nested.find().forEach(function(doc) {
    var document = {};
    document["name"] = doc.name.first_name + " " + doc.name.last_name;
    document["phone"] = doc.contact.phone.number;
    document["mail"] = doc.contact.email.mail;
    bulk.insert(document);
    counter++;
    if (counter % 1000 == 0) {
        bulk.execute();
        bulk = db.newcollection.initializeUnorderedBulkOp();
    }
});

> if (counter % 1000 != 0) { bulk.execute(); }

Sie werden etwas Ähnliches wie das Folgende sehen.

BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 1,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})

Führen Sie als Nächstes den folgenden Befehl auf Ihrer Mongo-Shell aus, um die projizierten Felder anzuzeigen.

// MongoDB version 5.0.8

> db.newcollection.find().pretty();

AUSGANG:

{
        "_id" : ObjectId("62a96f2d7c7e3688aea26d0e"),
        "name" : "Mehvish Ashiq",
        "phone" : "123456",
        "mail" : "delfstack@example.com"
}

Um diesen Beispielcode zu lernen, nehmen wir an, wir möchten bestimmte verschachtelte Felder greifen und sie in eine neue Sammlung einfügen. Hier kann sich das Einfügen der transformierten Felder als Dokument in eine neue Sammlung auf unsere Abläufe basierend auf der Größe der verschachtelten Sammlung auswirken.

Wir können diese langsame Einfügungsleistung vermeiden, indem wir eine neue ungeordnete Masseneinfügung-API verwenden. Es wird die Einfügevorgänge rationalisieren, indem es in großen Mengen gesendet wird, und uns in Echtzeit Feedback darüber geben, ob der Vorgang erfolgreich war oder fehlgeschlagen ist.

Wir verwenden also die bulk insert-API, um die gewünschte Datenstruktur in die newcollection-Sammlung einzufügen, wo die brandneuen Dokumente mit der forEach()-Schleife des verschachtelten Sammlungs-Cursors erstellt werden. Um neue Eigenschaften zu erstellen, verwenden wir die Klammernotation.

Für diesen Code gehen wir von einer großen Datenmenge aus. Also senden wir die Operationen in Stapeln von 1000 an einen Server, um die Masseneinfügeoperation durchzuführen.

Dadurch haben wir eine gute Leistung, da wir nicht jede Anfrage, sondern nur einmal alle 1000 Anfragen an den Server senden.

Verwenden Sie die Methode mapReduce(), um verschachtelte Felder in MongoDB zu projizieren

Beispielcode:

// MongoDB version 5.0.8

> function map() {
    for(var i in this.posting_locations) {
         emit({
             "country_id" : this.country_id,
             "city_id" : this.posting_locations[i].city_id,
             "region_id" : this.regions.region_id
         },1);
    }
}

> function reduce(id,docs) {
      return Array.sum(docs);
}

> db.nested.mapReduce(map,reduce,{ out : "map_reduce_output" } )

Führen Sie nun die folgende Abfrage aus, um die Ausgabe anzuzeigen.

// MongoDB version 5.0.8
> db.map_reduce_output.find().pretty();

AUSGANG:

{
        "_id" : {
                "country_id" : undefined,
                "city_id" : 19398,
                "region_id" : 796
        },
        "value" : 1
}
{
        "_id" : {
                "country_id" : undefined,
                "city_id" : 31022,
                "region_id" : 796
        },
        "value" : 1
}
{
        "_id" : {
                "country_id" : undefined,
                "city_id" : 31101,
                "region_id" : 796
        },
        "value" : 1
}

Für diesen Beispielcode verwenden wir die Funktion mapReduce(), um eine Map-Reduce für alle Dokumente der nested-Sammlung durchzuführen. Dazu müssen wir einem dreistufigen Prozess folgen, der unten kurz erläutert wird.

  • Definieren Sie die Funktion map(), um jedes Eingabedokument zu verarbeiten. In dieser Funktion bezieht sich das Schlüsselwort this auf das aktuelle Dokument, das von der Map-Reduce-Operation verarbeitet wird, und die Funktion emit() ordnet die angegebenen Werte den Schlüsseln zu und gibt sie zurück.
  • Hier definieren wir die entsprechende Funktion reduce(), das ist der eigentliche Ort, an dem die Aggregation der Daten stattfindet. Es braucht zwei Argumente (Schlüssel und Werte); unser Codebeispiel nimmt die id und docs.

    Denken Sie daran, dass die Elemente der docs von der Funktion emit() aus der Methode map() zurückgegeben werden. In diesem Schritt reduziert die Funktion reduce() das Array docs auf die Summe seiner Werte (Elemente).

  • Schließlich führen wir eine Kartenreduzierung für alle Dokumente in der verschachtelten Sammlung durch, indem wir die Funktionen map() und reduce() verwenden. Mit out speichern wir die Ausgabe in der angegebenen Collection, in diesem Fall map_reduce_output.
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Verwandter Artikel - MongoDB Projection