MongoDB Projekt verschachtelte Felder
- Verschachtelte Felder des MongoDB-Projekts
-
Verwenden Sie die
$project
Aggregationsstufe um verschachtelte Felder in MongoDB zu projizieren -
Verwenden Sie die Aggregationsstufe
$unset
um verschachtelte Felder ohne die angegebenen Felder in MongoDB zu erhalten -
Verwenden einer
forEach()
-Schleife zum Abrufen verschachtelter Felder in MongoDB -
Verwenden Sie die Methode
mapReduce()
, um verschachtelte Felder in MongoDB zu projizieren
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.
- Verwenden Sie die Aggregationsstufe
$project
- Verwenden Sie die Aggregationsstufe
$unset
- Verwenden Sie die
forEach()
-Schleife - 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üsselwortthis
auf das aktuelle Dokument, das von der Map-Reduce-Operation verarbeitet wird, und die Funktionemit()
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
undWerte
); unser Codebeispiel nimmt dieid
unddocs
.Denken Sie daran, dass die Elemente der
docs
von der Funktionemit()
aus der Methodemap()
zurückgegeben werden. In diesem Schritt reduziert die Funktionreduce()
das Arraydocs
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 Funktionenmap()
undreduce()
verwenden. Mitout
speichern wir die Ausgabe in der angegebenen Collection, in diesem Fallmap_reduce_output
.