MongoDB Referenzen verwenden

MongoDBBeginner
Jetzt üben

Einführung

In diesem Lab lernen Sie, wie Sie MongoDB-Referenzen zur Modellierung von Beziehungen zwischen Daten verwenden. Sie erstellen ein einfaches Bibliotheksverwaltungssystem mit den Sammlungen authors und books. Durch praktische Schritte lernen Sie, Dokumente zu erstellen, sie mithilfe von Referenzen zu verknüpfen, verwandte Daten über Sammlungen hinweg abzufragen, diese Referenzen zu aktualisieren und die Abfrageleistung mit Indizes zu verbessern. Dieses Lab bietet eine praktische Grundlage für die Datenmodellierung in MongoDB.

Sammlungen und Referenzdokumente erstellen

In diesem Schritt richten Sie Ihre Datenbank ein und erstellen zwei Sammlungen: authors und books. Sie lernen das grundlegende Konzept der Dokumentenreferenzierung, indem Sie ein Buch mit seinem Autor verknüpfen.

Öffnen Sie zuerst die MongoDB Shell. Diese interaktive Shell ist der Ort, an dem Sie alle Ihre Datenbankbefehle ausführen.

mongosh

Sobald Sie sich in der Shell befinden, sehen Sie eine Eingabeaufforderung test>. Wechseln Sie zu einer neuen Datenbank namens library_db. Wenn die Datenbank nicht existiert, erstellt MongoDB sie, wenn Sie zum ersten Mal Daten speichern.

use library_db

Erstellen Sie nun Ihren ersten Autor. Fügen Sie ein Dokument in die Sammlung authors ein. Wir geben für diesen Autor eine benutzerdefinierte _id an, um die spätere Referenzierung zu erleichtern.

db.authors.insertOne({
    _id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
    name: "Jane Austen",
    nationality: "British",
    birthYear: 1775
})

Fügen Sie als Nächstes ein Dokument in die Sammlung books ein. Das Feld author_id enthält die ObjectId des gerade erstellten Autors. So erstellen Sie eine Referenz.

db.books.insertOne({
    title: "Pride and Prejudice",
    author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
    published: 1813,
    genre: "Classic Literature"
})

Sie haben nun eine Eins-zu-Eins-Beziehung erstellt. Um dies zu überprüfen, können Sie die gerade erstellten Dokumente abrufen.

Finden Sie zuerst den Autor:

db.authors.findOne({ name: "Jane Austen" })

Beispielausgabe:

{
  _id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
  name: 'Jane Austen',
  nationality: 'British',
  birthYear: 1775
}

Finden Sie nun das Buch und beachten Sie das Feld author_id, das auf den Autor verweist.

db.books.findOne({ title: "Pride and Prejudice" })

Beispielausgabe:

{
  _id: ObjectId("..."),
  title: 'Pride and Prejudice',
  author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
  published: 1813,
  genre: 'Classic Literature'
}

Sie können für die nächsten Schritte in der mongosh-Shell bleiben.

Mehrere Dokumente verknüpfen

Ein Autor schreibt normalerweise mehr als ein Buch. In diesem Schritt lernen Sie, wie Sie mehrere "Kind"-Dokumente (Bücher) mit einem einzigen "Eltern"-Dokument (Autor) verknüpfen. Dies demonstriert eine Eins-zu-Viele-Beziehung.

Arbeiten Sie weiterhin in der mongosh-Shell. Fügen wir zwei weitere Bücher von Jane Austen hinzu. Verwenden Sie den Befehl insertMany, um mehrere Dokumente auf einmal einzufügen. Beide neuen Bücher werden auf dieselbe author_id verweisen.

db.books.insertMany([
    {
        title: "Sense and Sensibility",
        author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
        published: 1811,
        genre: "Classic Literature"
    },
    {
        title: "Emma",
        author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
        published: 1815,
        genre: "Classic Literature"
    }
])

Da Jane Austen nun drei Bücher in unserer Datenbank hat, rufen Sie alle mit der Methode find() ab und filtern nach author_id.

db.books.find({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1") })

Beispielausgabe:

[
  {
    _id: ObjectId("..."),
    title: 'Pride and Prejudice',
    author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
    published: 1813,
    genre: 'Classic Literature'
  },
  {
    _id: ObjectId("..."),
    title: 'Sense and Sensibility',
    author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
    published: 1811,
    genre: 'Classic Literature'
  },
  {
    _id: ObjectId("..."),
    title: 'Emma',
    author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
    published: 1815,
    genre: 'Classic Literature'
  }
]

Sie können auch schnell zählen, wie viele Bücher mit einem bestimmten Autor verknüpft sind, indem Sie countDocuments verwenden.

db.books.countDocuments({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1") })

Beispielausgabe:

3

Diese einfache Abfrage bestätigt effizient die Anzahl der verknüpften Dokumente.

Abfragen über Sammlungen mit $lookup

Bisher haben Sie Bücher mithilfe einer bekannten author_id abgerufen. Ein leistungsfähigerer Ansatz ist die Kombination von Daten aus beiden Sammlungen in einer einzigen Abfrage. In diesem Schritt verwenden Sie die Aggregationsstufe $lookup, um einen linken äußeren Join von der books-Sammlung zur authors-Sammlung durchzuführen.

Fügen Sie zunächst einen weiteren Autor und ein weiteres Buch hinzu, um unsere Abfrage interessanter zu gestalten.

db.authors.insertOne({
    _id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
    name: "Charles Dickens",
    nationality: "British",
    birthYear: 1812
})
db.books.insertOne({
    title: "Oliver Twist",
    author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
    published: 1837,
    genre: "Historical Fiction"
})

Erstellen Sie nun eine Aggregationspipeline. Diese Abfrage beginnt mit der books-Sammlung und "sucht" nach dem passenden Autor für jedes Buch.

db.books.aggregate([
    {
        $lookup: {
            from: "authors",
            localField: "author_id",
            foreignField: "_id",
            as: "author_details"
        }
    }
])

Die $lookup-Stufe hat die folgenden Felder:

  • from: "authors": Gibt die Sammlung an, mit der verbunden werden soll.
  • localField: "author_id": Das Feld aus den Eingabedokumenten (aus books).
  • foreignField: "_id": Das Feld aus den Dokumenten der "from"-Sammlung (aus authors).
  • as: "author_details": Der Name für das neue Array-Feld, das den Eingabedokumenten hinzugefügt wird.

Beispielausgabe (für ein Dokument):

{
  _id: ObjectId("..."),
  title: 'Pride and Prejudice',
  author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
  published: 1813,
  genre: 'Classic Literature',
  author_details: [
    {
      _id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
      name: 'Jane Austen',
      nationality: 'British',
      birthYear: 1775
    }
  ]
}

Wie Sie sehen können, sind die Informationen des Autors nun innerhalb jedes Buchdokuments unter dem Feld author_details eingebettet. Dies ermöglicht es Ihnen, gleichzeitig auf Felder aus beiden Sammlungen zuzugreifen.

Referenzen aktualisieren und pflegen

Daten sind nicht immer statisch. Möglicherweise müssen Sie Fehler korrigieren oder Daten entfernen, was das Aktualisieren oder Löschen von Dokumenten und deren Referenzen erfordert. In diesem Schritt lernen Sie, wie Sie eine Referenz aktualisieren und "verwaiste" Dokumente behandeln.

Stellen Sie sich vor, Sie stellen fest, dass das Buch "Emma" fälschlicherweise Jane Austen zugeschrieben wurde und Charles Dickens zugeordnet werden sollte. Sie können dies mit dem Befehl updateOne und dem Operator $set korrigieren.

db.books.updateOne(
    { title: "Emma" },
    { $set: { author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2") } }
)

Überprüfen Sie die Änderung, indem Sie das Buch erneut suchen und seine author_id überprüfen.

db.books.findOne({ title: "Emma" })

Beispielausgabe:

{
  _id: ObjectId("..."),
  title: 'Emma',
  author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
  published: 1815,
  genre: 'Classic Literature'
}

Betrachten wir nun, was passiert, wenn ein Elterndokument gelöscht wird. Wenn wir einen Autor löschen, werden alle Bücher, die auf diesen Autor verweisen, zu "verwaisten" Dokumenten. Löschen wir Charles Dickens aus unserer Datenbank.

db.authors.deleteOne({ name: "Charles Dickens" })

Das Autordokument ist weg, aber die Bücher "Emma" und "Oliver Twist" haben immer noch eine author_id, die auf den gelöschten Autor verweist. Dies kann zu Problemen mit der Datenintegrität führen. In einer realen Anwendung würden Sie eine Logik implementieren, um dies zu handhaben, z. B. das Löschen der verwaisten Bücher oder deren Neuzuweisung.

Für dieses Lab räumen wir manuell auf, indem wir die beiden verwaisten Bücher löschen.

db.books.deleteMany({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2") })

Dieser Befehl entfernt alle Dokumente aus der books-Sammlung, die auf den nun gelöschten Autor verweisen, und stellt so sicher, dass unsere Daten konsistent bleiben.

Abfrageleistung mit Indizes verbessern

Wenn Ihre Sammlungen wachsen, können Abfragen, die nach einem bestimmten Feld filtern, langsam werden. Dies liegt daran, dass MongoDB jedes Dokument durchsuchen muss, um Übereinstimmungen zu finden. Um dies zu optimieren, können Sie einen Index für die Felder erstellen, die Sie häufig abfragen. In unserem Fall ist author_id in der books-Sammlung ein perfekter Kandidat.

In diesem Schritt erstellen Sie einen Index für das Feld author_id, um die Abfragen nach Büchern eines Autors zu beschleunigen.

Verwenden Sie den Befehl createIndex für die books-Sammlung. Das Argument { author_id: 1 } weist MongoDB an, einen aufsteigenden Index für das Feld author_id zu erstellen.

db.books.createIndex({ author_id: 1 })

MongoDB wird dies im Hintergrund verarbeiten. Sobald es abgeschlossen ist, wird eine Meldung zurückgegeben, die bestätigt, dass der Index erstellt wurde.

Beispielausgabe:

{
  "numIndexesBefore": 1,
  "numIndexesAfter": 2,
  "createdCollectionAutomatically": false,
  "ok": 1
}

Um zu überprüfen, ob der Index vorhanden ist, können Sie den Befehl getIndexes verwenden. Dieser listet alle Indizes in der books-Sammlung auf.

db.books.getIndexes()

Sie sollten zwei Indizes sehen: den Standardindex für _id und den neuen author_id_1-Index, den Sie gerade erstellt haben.

Beispielausgabe:

[
  { "v": 2, "key": { "_id": 1 }, "name": "_id_" },
  { "v": 2, "key": { "author_id": 1 }, "name": "author_id_1" }
]

Mit diesem Index werden alle Abfragen, die nach author_id filtern oder sortieren, einschließlich der zuvor verwendeten $lookup-Stufe, bei großen Datensätzen erheblich schneller.

Schließlich können Sie die MongoDB-Shell beenden.

exit

Zusammenfassung

In diesem Lab haben Sie die Grundlagen der Verwendung von Dokumentreferenzen in MongoDB gelernt. Sie haben mit der Erstellung von Sammlungen und der Verknüpfung von Dokumenten mit ObjectId-Referenzen begonnen. Anschließend haben Sie die Verwaltung von Eins-zu-Viele-Beziehungen geübt, Abfragen über Sammlungen hinweg mit der leistungsstarken $lookup-Aggregationsstufe durchgeführt und die Datenintegrität durch Aktualisierung und Bereinigung von Referenzen aufrechterhalten. Schließlich haben Sie die Abfrageleistung durch die Erstellung eines Index für ein Referenzfeld verbessert. Diese Fähigkeiten sind unerlässlich für die Entwicklung skalierbarer und effizienter Anwendungen mit MongoDB.