Advertisement
  1. Code
  2. Node.js

Eine Einführung in Mongoose für MongoDB und Node.js

by
Read Time:18 minsLanguages:
This post is part of a series called An Introduction to Mongoose for MongoDB and Node.js.
Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js

German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)

Mongoose ist ein JavaScript-Framework, das häufig in einer Node.js-Anwendung mit einer MongoDB-Datenbank verwendet wird. In diesem Artikel werde ich Ihnen Mongoose und MongoDB vorstellen und noch wichtiger, wo diese Technologien in Ihre Anwendung passen.

Was ist MongoDB?

Beginnen wir mit MongoDB. MongoDB ist eine Datenbank, die Ihre Daten als Dokumente speichert. Am häufigsten ähneln diese Dokumente einer JSON-ähnlichen Struktur:

Ein Dokument wird dann innerhalb einer Sammlung platziert. Als Beispiel definiert das obige Dokumentbeispiel ein user-Objekt. Dieses user-Objekt wäre dann normalerweise Teil einer Sammlung namens users.

Einer der Schlüsselfaktoren von MongoDB ist seine Flexibilität in Bezug auf die Struktur. Obwohl das user-Objekt im ersten Beispiel eine firstName- und lastName-Eigenschaft enthielt, sind diese Eigenschaften nicht in jedem user-Dokument erforderlich, das Teil der users-Sammlung ist. Dies unterscheidet MongoDB stark von einer SQL-Datenbank wie MySQL oder Microsoft SQL Server, die ein streng definiertes Datenbankschema für jedes gespeicherte Objekt erfordert.

Die Möglichkeit, dynamische Objekte zu erstellen, die als Dokumente in der Datenbank gespeichert werden, ist der Punkt, an dem Mongoose ins Spiel kommt.

Was ist Mongoose?

Mongoose ist ein Object Document Mapper (ODM). Dies bedeutet, dass Sie mit Mongoose Objekte mit einem stark typisierten Schema definieren können, das einem MongoDB-Dokument zugeordnet ist.

Mongoose bietet unglaublich viele Funktionen rund um das Erstellen und Arbeiten mit Schemas. Mongoose enthält derzeit acht SchemaTypes, mit denen eine Eigenschaft gespeichert wird, wenn sie in MongoDB beibehalten wird. Sie sind:

  1. String
  2. Number
  3. Date
  4. Buffer
  5. Boolean
  6. Mixed
  7. ObjectId
  8. Array

Für jeden Datentyp können Sie Folgendes angeben:

  • ein Standardwert
  • eine benutzerdefinierte Validierungsfunktion
  • angeben, dass ein Feld erforderlich ist
  • eine Get-Funktion, mit der Sie die Daten manipulieren können, bevor sie als Objekt zurückgegeben werden
  • eine Set-Funktion, mit der Sie die Daten manipulieren können, bevor sie in der Datenbank gespeichert werden
  • Erstellen Sie Indizes, damit Daten schneller abgerufen werden können

Neben diesen allgemeinen Optionen ermöglichen Ihnen bestimmte Datentypen, die Art und Weise, wie die Daten gespeichert und aus der Datenbank abgerufen werden, weiter anzupassen. Mit einem String-Datentyp können Sie beispielsweise auch die folgenden zusätzlichen Optionen angeben:

  • in Kleinbuchstaben umwandeln
  • in Großbuchstaben umwandeln
  • Daten vor dem Speichern trimmen
  • ein regulärer Ausdruck, der Daten einschränken kann, die während des Validierungsprozesses gespeichert werden dürfen
  • eine Aufzählung, die eine Liste gültiger Zeichenfolgen definieren kann

Die Eigenschaften Number und Date unterstützen beide die Angabe eines minimalen und maximalen Werts, der für dieses Feld zulässig ist.

Die meisten der acht erlaubten Datentypen sollten Ihnen bekannt sein. Es gibt jedoch einige Ausnahmen, die Ihnen möglicherweise auffallen, z. B. Buffer, Mixed, ObjectId und Array.

Der Datentyp Buffer ermöglicht das Speichern von Binärdaten. Ein gängiges Beispiel für Binärdaten wäre ein Bild oder eine codierte Datei, beispielsweise ein PDF-Dokument.

Der Datentyp Mixed verwandelt die Eigenschaft in ein "anything goes"-Feld. Dieses Feld ähnelt der Anzahl der Entwickler, die MongoDB verwenden können, da keine definierte Struktur vorhanden ist. Seien Sie vorsichtig bei der Verwendung dieses Datentyps, da viele der großartigen Funktionen von Mongoose verloren gehen, z. B. die Datenvalidierung und das Erkennen von Entitätsänderungen, um die Eigenschaft beim Speichern automatisch zu aktualisieren.

Der Datentyp ObjectId gibt normalerweise einen Link zu einem anderen Dokument in Ihrer Datenbank an. Wenn Sie beispielsweise über eine Sammlung von Büchern und Autoren verfügen, kann das Buchdokument eine ObjectId-Eigenschaft enthalten, die auf den jeweiligen Autor des Dokuments verweist.

Mit dem Datentyp Array können Sie JavaScript-ähnliche Arrays speichern. Mit einem Array-Datentyp können Sie gängige JavaScript-Array-Operationen wie Push, Pop, Shift, Slice usw. ausführen.

Kurze Zusammenfassung

Bevor ich fortfuhr und Code generierte, wollte ich nur zusammenfassen, was wir gerade gelernt haben. MongoDB ist eine Datenbank, mit der Sie Dokumente mit einer dynamischen Struktur speichern können. Diese Dokumente werden in einer Sammlung gespeichert.

Mongoose ist eine JavaScript-Bibliothek, mit der Sie Schemata mit stark typisierten Daten definieren können. Sobald ein Schema definiert ist, können Sie mit Mongoose ein Modell basierend auf einem bestimmten Schema erstellen. Ein Mongoose-Modell wird dann über die Schemadefinition des Modells einem MongoDB-Dokument zugeordnet.

Nachdem Sie Ihre Schemata und Modelle definiert haben, enthält Mongoose viele verschiedene Funktionen, mit denen Sie Ihre Daten mit gängigen MongoDB-Funktionen validieren, speichern, löschen und abfragen können. Ich werde dies anhand der folgenden konkreten Codebeispiele näher erläutern.

MongoDB installieren

Bevor wir mit der Erstellung unserer Mongoose-Schemas und -Modelle beginnen können, muss MongoDB installiert und konfiguriert werden. Ich würde vorschlagen, die Download-Seite von MongoDB zu besuchen. Für die Installation stehen verschiedene Optionen zur Verfügung. Ich habe mit dem Community-Server verlinkt. Auf diese Weise können Sie eine für Ihr Betriebssystem spezifische Version installieren. MongoDB bietet auch einen Enterprise Server und eine Cloud-Support-Installation. Da man ganze Bücher über die Installation, Optimierung und Überwachung von MongoDB schreiben könnte, bleibe ich beim Community Server.

Nachdem Sie MongoDB für das Betriebssystem Ihrer Wahl heruntergeladen und installiert haben, müssen Sie die Datenbank starten. Anstatt das Rad neu zu erfinden, würde ich vorschlagen, die MongoDB-Dokumentation zur Installation der MongoDB Community Edition zu besuchen.

Ich warte hier, während Sie MongoDB konfigurieren. Wenn Sie bereit sind, können wir mit der Einrichtung von Mongoose fortfahren, um eine Verbindung zu Ihrer neu installierten MongoDB-Datenbank herzustellen.

Mongoose Einrichtug

Mongoose ist ein JavaScript-Framework, und ich werde es in einer Node.js-Anwendung verwenden. Wenn Node.js bereits installiert ist, können Sie mit dem nächsten Schritt fortfahren. Wenn Node.js nicht installiert ist, schlage ich vor, dass Sie zunächst die Downloadseite von Node.js besuchen und das Installationsprogramm für Ihr Betriebssystem auswählen.

Wenn Node.js eingerichtet und einsatzbereit ist, werde ich eine neue Anwendung erstellen und dann das Mongoose NPM-Paket installieren.

Mit einer Eingabeaufforderung, die so eingestellt ist, dass Ihre Anwendung installiert werden soll, können Sie die folgenden Befehle ausführen:

Für die Initialisierung meiner Anwendung habe ich alles auf den Standardwerten belassen. Jetzt installiere ich das Mongoose-Paket wie folgt:

Wenn alle Voraussetzungen konfiguriert sind, stellen wir eine Verbindung zu einer MongoDB-Datenbank her. Ich habe den folgenden Code in eine index.js-Datei eingefügt, weil ich dies als Ausgangspunkt für meine Anwendung gewählt habe:

Die erste Codezeile enthält die mongoose-Bibliothek. Als nächstes öffne ich eine Verbindung zu einer Datenbank, die ich mongoose_basics genannt habe, indem ich die Funktion connect verwende.

Die connect-Funktion akzeptiert zwei weitere optionale Parameter. Der zweite Parameter ist ein Optionsobjekt, in dem Sie bei Bedarf Dinge wie den Benutzernamen und das Passwort definieren können. Der dritte Parameter, der auch der zweite Parameter sein kann, wenn Sie keine Optionen haben, ist die Callback-Funktion nach dem Verbindungsversuch. Die Callback-Funktion kann auf zwei Arten verwendet werden:

Um eine mögliche Einführung in JavaScript Promises zu vermeiden, werde ich den ersten Weg verwenden. Unten ist eine aktualisierte index.js-Datei:

Tritt beim Verbinden mit der Datenbank ein Fehler auf, wird die Ausnahme ausgelöst und die weitere Verarbeitung gestoppt. Wenn kein Fehler auftritt, habe ich eine Erfolgsmeldung in der Konsole protokolliert.

Mongoose ist nun eingerichtet und mit einer Datenbank namens mongoose_basics verbunden. Meine MongoDB-Verbindung verwendet keinen Benutzernamen, kein Passwort oder einen benutzerdefinierten Port. Wenn Sie diese Optionen oder eine andere Option während der Verbindung einstellen müssen, empfehle ich Ihnen, die Mongoose-Dokumentation zum Herstellen einer Verbindung zu lesen. Die Dokumentation bietet detaillierte Erklärungen zu den vielen verfügbaren Optionen sowie zum Erstellen von Mehrfachverbindungen, Verbindungspooling, Replikaten usw.

Nach erfolgreicher Verbindung können wir ein Mongoose-Schema definieren.

Definieren eines Mongoose-Schemas

Während der Einführung habe ich ein user-Objekt gezeigt, das zwei Eigenschaften enthält: firstName und lastName. Im folgenden Beispiel habe ich dieses Dokument in ein Mongoose-Schema übersetzt:

Dies ist ein sehr einfaches Schema, das nur zwei Eigenschaften ohne zugeordnete Attribute enthält. Lassen Sie uns dieses Beispiel erweitern, indem wir die Vor- und Nachnameneigenschaften in untergeordnete Objekte einer name-Eigenschaft konvertieren. Die name-Eigenschaft umfasst sowohl den Vor- als auch den Nachnamen. Ich füge auch eine created Eigenschaft vom Typ Date hinzu.

Wie Sie sehen, kann ich mit Mongoose sehr flexible Schemata mit vielen verschiedenen Kombinationsmöglichkeiten erstellen, wie ich meine Daten organisieren kann.

In diesem nächsten Beispiel werde ich zwei neue Schemas erstellen, die zeigen, wie eine Beziehung zu einem anderen Schema erstellt wird: author und book. Das book-Schema enthält einen Verweis auf das author-Schema.

Oben sehen Sie das author-Schema, das die Konzepte des user-Schemas erweitert, das ich im vorherigen Beispiel erstellt habe. Um Autor und Buch miteinander zu verknüpfen, ist die erste Eigenschaft des author-Schemas eine _id-Eigenschaft, die ein ObjectId-Schematyp ist. _id ist die allgemeine Syntax zum Erstellen eines Primärschlüssels in Mongoose und MongoDB. Dann habe ich wie beim user-Schema eine name-Eigenschaft definiert, die den Vor- und Nachnamen des Autors enthält.

Der author erweitert das user-Schema und enthält mehrere andere String-Schematypen. Ich habe auch einen Buffer-Schematyp hinzugefügt, der das Profilbild des Autors enthalten könnte. Die letzte Eigenschaft enthält das Erstellungsdatum des Autors; Sie werden jedoch möglicherweise feststellen, dass es etwas anders erstellt wird, da der Standardwert "jetzt" definiert ist. Wenn ein Autor in der Datenbank gespeichert wird, wird diese Eigenschaft auf das aktuelle Datum/die aktuelle Uhrzeit gesetzt.

Um die Schemabeispiele zu vervollständigen, erstellen wir mithilfe des Schematyps ObjectId ein book-Schema, das einen Verweis auf den Autor enthält:

Das book-Schema enthält mehrere Eigenschaften vom Typ String. Wie oben erwähnt, enthält es einen Verweis auf das author-Schema. Um die leistungsstarken Schemadefinitionen weiter zu demonstrieren, enthält das book-Schema auch ein Array von ratings. Jede Bewertung besteht aus einer summary, einem detail, einer numberOfStars und einer created Datumseigenschaft.

Mongoose bietet Ihnen die Flexibilität, Schemata mit Verweisen auf andere Schemas zu erstellen oder, wie im obigen Beispiel mit der ratings-Eigenschaft, ein Array von untergeordneten Eigenschaften zu erstellen, die in einem verwandten Schema enthalten sein könnten (z. B. Buch zum Autor) oder inline wie im obigen Beispiel (mit book to a ratings Array).

Mongoose-Modelle erstellen und speichern

Da die Schemas des author und des book die Schemaflexibilität von Mongoose demonstrieren, werde ich diese Schemata weiterhin verwenden und daraus ein Author- und Book-Modell ableiten.

Ein Mongoose-Modell erstellt beim Speichern ein Dokument in MongoDB mit den Eigenschaften, die durch das Schema definiert sind, von dem es abgeleitet ist.

Um das Erstellen und Speichern eines Objekts zu demonstrieren, werde ich im nächsten Beispiel mehrere Objekte erstellen: ein Author-Modell und mehrere Book-Modelle. Nach der Erstellung werden diese Objekte mithilfe der save-Methode des Modells in MongoDB gespeichert.

Im obigen Beispiel habe ich schamlos einen Verweis auf meine beiden neuesten Bücher eingefügt. Das Beispiel beginnt mit dem Erstellen und Speichern eines jamieObject, das aus einem Author-Modell erstellt wird. Innerhalb der save-Funktion von jamieObject gibt die Anwendung im Fehlerfall eine Ausnahme aus. Wenn das Speichern erfolgreich ist, werden innerhalb der save-Funktion die beiden Buchobjekte erstellt und gespeichert. Wenn beim Speichern ein Fehler auftritt, wird ähnlich wie beim jamieObject ein Fehler ausgegeben; andernfalls wird in der Konsole eine Erfolgsmeldung ausgegeben.

Um die Referenz auf den Autor zu erstellen, verweisen die Buchobjekte beide auf den _id-Primärschlüssel des author-Schemas in der author-Eigenschaft des book-Schemas.

Daten vor dem Speichern validieren

Es ist durchaus üblich, dass die Daten, aus denen ein Modell erstellt wird, von einem Formular auf einer Webseite ausgefüllt werden. Aus diesem Grund ist es eine gute Idee, diese Daten vor dem Speichern des Modells in MongoDB zu validieren.

In diesem nächsten Beispiel habe ich das vorherige Autorenschema aktualisiert, um die Validierung der folgenden Eigenschaften hinzuzufügen: firstName, twitter, facebook und linkedin.

Der firstName-Eigenschaft wurde die required Eigenschaft zugeordnet. Wenn ich jetzt die save-Funktion aufrufe, gibt Mongoose einen Fehler mit einer Meldung zurück, die darauf hinweist, dass die Eigenschaft firstName erforderlich ist. Ich habe mich entschieden, die lastName-Eigenschaft nicht erforderlich zu machen, falls Cher oder Madonna Autoren in meiner Datenbank sein sollten.

Auf die twitter-, facebook- und linkedin-Eigenschaften werden alle sehr ähnliche benutzerdefinierte Validatoren angewendet. Sie stellen jeweils sicher, dass die Werte mit dem jeweiligen Domainnamen der sozialen Netzwerke beginnen. Diese Felder sind nicht erforderlich, daher wird der Validator nur angewendet, wenn Daten für diese Eigenschaft bereitgestellt werden.

Suchen und Aktualisieren von Daten

Eine Einführung in Mongoose wäre ohne ein Beispiel für die Suche nach einem Datensatz und das Aktualisieren einer oder mehrerer Eigenschaften für dieses Objekt nicht vollständig.

Mongoose bietet verschiedene Funktionen, um Daten für ein bestimmtes Modell zu finden. Die Funktionen sind find, findOne und findById.

Die Funktionen find und findOne akzeptieren beide ein Objekt als Eingabe, was komplexe Suchen ermöglicht, während findById nur einen einzelnen Wert mit einer Callback-Funktion akzeptiert (ein Beispiel folgt in Kürze). In diesem nächsten Beispiel werde ich zeigen, wie Sie alle Bücher finden, deren Titel die Zeichenfolge "mvc" enthalten.

In der find-Funktion suche ich nach der Zeichenfolge "mvc", die die Groß-/Kleinschreibung nicht berücksichtigt, in der title-Eigenschaft. Dies wird mit der gleichen Syntax wie beim Durchsuchen eines Strings mit JavaScript erreicht.

Der Funktionsaufruf find kann auch mit anderen Abfragemethoden verkettet werden, z. B. where, and, or, limit, sort, any usw.

Lassen Sie uns das vorherige Beispiel erweitern, um unsere Ergebnisse auf die ersten fünf Bücher zu beschränken und nach dem Erstellungsdatum absteigend zu sortieren. Dadurch werden bis zu den fünf neuesten Büchern zurückgegeben, die "mvc" im Titel enthalten.

Nach dem Anwenden der find-Funktion ist die Reihenfolge der anderen Funktionen nicht wichtig, da alle verketteten Funktionen zu einer einzigen Abfrage kompiliert und erst beim Aufruf der exec-Funktion ausgeführt werden.

Wie ich bereits erwähnt habe, wird findById etwas anders ausgeführt. Es wird sofort ausgeführt und akzeptiert eine Callback-Funktion, anstatt eine Kette von Funktionen zuzulassen. In diesem nächsten Beispiel frage ich einen bestimmten Autor nach seiner _id ab.

Die _id kann in Ihrem Fall etwas anders sein. Ich habe diese _id aus einer früheren console.log kopiert, als ich eine Liste von Büchern mit "mvc" im Titel gefunden habe.

Nachdem ein Objekt zurückgegeben wurde, können Sie seine Eigenschaften ändern, um es zu aktualisieren. Nachdem Sie die notwendigen Änderungen vorgenommen haben, rufen Sie die Methode save wie beim Anlegen des Objekts auf. In diesem nächsten Beispiel erweitere ich das findbyId-Beispiel und aktualisiere die linkedin-Eigenschaft des Autors.

Nachdem der Autor erfolgreich abgerufen wurde, wird die Eigenschaft linkedin gesetzt und die save-Funktion aufgerufen. Mongoose kann erkennen, dass die linkedin-Eigenschaft geändert wurde, und sendet eine Update-Anweisung an MongoDB nur für die geänderten Eigenschaften. Wenn beim Speichern ein Fehler aufgetreten ist, wird eine Ausnahme ausgelöst und die Anwendung angehalten. Bei Erfolg wird eine Erfolgsmeldung an der Konsole protokolliert.

Mongoose bietet außerdem zwei zusätzliche Funktionen, die das Auffinden und Speichern eines Objekts mit den entsprechend benannten Funktionen in einem Schritt ermöglichen: findByIdAndUpdate und findOneAndUpdate. Lassen Sie uns das vorherige Beispiel aktualisieren, um findByIdAndUpdate zu verwenden.

Im vorherigen Beispiel werden die zu aktualisierenden Eigenschaften als Objekt an den zweiten Parameter der Funktion findByIdAndUpdate übergeben. Die Callback-Funktion ist nun der dritte Parameter. Wenn die Aktualisierung erfolgreich ist, enthält das zurückgegebene author-Objekt die aktualisierten Informationen. Dies wird in der Konsole protokolliert, um die Eigenschaften des aktualisierten Autors anzuzeigen.

Endgültiger Beispielcode

In diesem Artikel habe ich kleine Code-Schnipsel bereitgestellt, die eine sehr spezifische Aktion identifizieren, z. B. das Erstellen eines Schemas, Erstellen eines Modells usw. Lassen Sie uns alles in einem vollständigen Beispiel zusammenfassen.

Zuerst habe ich zwei zusätzliche Dateien erstellt: author.js und book.js. Diese Dateien enthalten ihre jeweiligen Schemadefinitionen und die Modellerstellung. Die letzte Codezeile macht das Modell für die Verwendung in der Datei index.js verfügbar.

Beginnen wir mit der Datei author.js:

Danach kommt die Datei book.js:

Und schließlich die aktualisierte Datei index.js:

Im obigen Beispiel sind alle Mongoose-Aktionen in der connect-Funktion enthalten. Die author- und book-Dateien werden nach Einbindung der mongoose-Bibliothek in die require-Funktion eingebunden.

Wenn MongoDB ausgeführt wird, können Sie jetzt die vollständige Node.js-Anwendung mit dem folgenden Befehl ausführen:

Nachdem ich einige Daten in meiner Datenbank gespeichert habe, habe ich die Datei index.js mit den Suchfunktionen wie folgt aktualisiert:

Sie können die Anwendung erneut mit dem Befehl ausführen: node index.js.

Zusammenfassung

Nachdem Sie diesen Artikel gelesen haben, sollten Sie in der Lage sein, äußerst flexible Mongoose-Schemas und -Modelle zu erstellen, einfache oder komplexe Validierungen durchzuführen, Dokumente zu erstellen und zu aktualisieren und schließlich nach den erstellten Dokumenten zu suchen.

Hoffentlich fühlen Sie sich jetzt mit Mongoose wohl. Wenn Sie mehr erfahren möchten, empfehle ich Ihnen, die Mongoose-Leitfäden zu lesen, die sich mit fortgeschritteneren Themen wie Bevölkerung, Middleware, Versprechen usw.

Viel Spaß beim Jagen (schlechte Mungotierreferenz)!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.