M165 NoSQL Datenbanken | Block 05¶
Inhaltsverzeichnis¶
Theorie¶
Was ist eine Graphendatenbank?¶
Eine Graphdatenbank speichert Daten in Form von Knoten (Objekte) und Kanten (Beziehungen). Sie ist darauf optimiert, Verbindungen zwischen Datenpunkten extrem schnell zu verfolgen.
Besonders nützlich für:
-
Soziale Netzwerke: "Wer ist mit wem befreundet?" oder "Freunde von Freunden".
-
Empfehlungs-Engines: "Kunden, die das kauften, kauften auch..."
-
Betrugserkennung: Aufspüren von komplexen Mustern in Transaktionsketten.
-
Netzwerk-Management: Darstellung von IT-Infrastrukturen und deren Abhängigkeiten.
Begriffe MongoDB¶
| Begriff | Erklärung |
|---|---|
| Datenbank (Database) | Eine Sammlung von Dokumenten, die in einer MongoDB-Instanz gespeichert sind. |
| Sammlung (Collection) | Eine Gruppe von Dokumenten in einer Datenbank. Sammlungen sind vergleichbar mit Tabellen in relationalen Datenbanken. |
| Dokument (Document) | Die grundlegende Dateneinheit in MongoDB, gespeichert im BSON-Format. Ähnlich wie eine Zeile in einer relationalen Datenbank. |
| Feld (Field) | Ein Schlüssel-Wert-Paar innerhalb eines Dokuments. Entspricht einer Spalte in einer relationalen Datenbank. |
| Index | Eine Datenstruktur, die die Geschwindigkeit von Abfragen in MongoDB verbessert. |
| BSON | Binary JSON. Das Standardformat für die Speicherung von Dokumenten in MongoDB. BSON unterstützt alle JSON-Typen plus zusätzliche Datentypen. |
| Replica Set | Eine Gruppe von MongoDB-Instanzen, die dieselben Daten speichern, um die Verfügbarkeit und Redundanz zu gewährleisten. |
| Sharding | Eine Methode zur Verteilung von Daten über mehrere Server, um grosse Datenmengen zu verwalten. |
| Aggregation | Ein Prozess zur Verarbeitung von Daten, um Werte zu berechnen oder zu transformieren, oft unter Verwendung der Aggregation-Pipeline. |
| MapReduce | Ein Aggregationsverfahren, das in MongoDB verwendet wird, um Daten in einer verteilten Weise zu verarbeiten. |
| Cursor | Ein Zeiger auf das Abfrageergebnis, das durch die find()-Methode zurückgegeben wird. Ein Cursor ermöglicht das Durchlaufen von Dokumenten. |
| GridFS | Ein Speichersystem für grosse Dateien (z.B. Bilder, Videos), das in MongoDB verwendet wird. Dateien werden in kleinere Teile zerlegt und verteilt gespeichert. |
| Write Concern | Eine Einstellung, die bestimmt, wie viele MongoDB-Server bestätigen müssen, dass eine Schreiboperation erfolgreich war. |
| Read Concern | Eine Einstellung, die bestimmt, welche Datenlesekonsistenz gewährleistet sein muss. |
| Aggregation Pipeline | Eine Reihe von Stufen, die in MongoDB verwendet werden, um Daten zu transformieren und zu aggregieren. |
| Transaction | Eine Operation oder ein Satz von Operationen, die als atomar betrachtet werden, um Konsistenz und Integrität der Daten zu gewährleisten. |
| Replication | Der Prozess, bei dem Daten von einem primären MongoDB-Server auf einen oder mehrere sekundäre Server kopiert werden, um Ausfallsicherheit und Verfügbarkeit zu erhöhen. |
Basic Commands¶
| Befehl | Beschreibung |
|---|---|
mongosh |
Öffnet eine Verbindung zu deiner lokalen MongoDB-Instanz. |
db.help() |
Zeigt Hilfe zu Datenbankmethoden an. |
db.<collection>.help() |
Zeigt Hilfe zu methodenspezifischen Sammlungen an. |
show dbs |
Listet alle Datenbanken auf dem Server auf. |
use <db> |
Wechselt zur angegebenen Datenbank. |
show collections |
Listet alle Sammlungen in der aktuellen Datenbank auf. |
show users |
Zeigt alle Benutzer der aktuellen Datenbank an. |
show roles |
Zeigt alle Rollen (benutzerdefiniert und integriert) für die aktuelle Datenbank an. |
show profile |
Zeigt die fünf letzten Operationen, die mindestens 1ms dauerten, bei aktivem Profiling an. |
show databases |
Listet alle zugänglichen Datenbanken für den aktuellen Benutzer auf. |
exit |
Beendet die MongoDB-Shell (mongosh). |
Create Operations¶
| Befehl | Beschreibung |
|---|---|
db.collection.insertOne() |
Fügt ein einzelnes Dokument in eine Sammlung ein. |
db.users.insertOne({ name: "Chris" }) |
Fügt ein neues Dokument mit dem Namen "Chris" in die Sammlung users ein. |
db.collection.insertMany() |
Fügt mehrere Dokumente in eine Sammlung ein. |
db.users.insertMany([{ age: 24 }, { age: 38 }]) |
Fügt zwei neue Dokumente mit den Altersangaben 24 und 38 in die Sammlung users ein. |
Read Operations¶
| Befehl | Beschreibung |
|---|---|
db.collection.find() |
Wählt Dokumente in einer Sammlung aus und gibt einen Cursor für die ausgewählten Dokumente zurück. |
db.users.find() |
Gibt alle Dokumente in der Sammlung users zurück. |
db.collection.find(<filterobject>) |
Findet alle Dokumente, die dem angegebenen Filter entsprechen. |
db.users.find({ place: "NYC" }) |
Gibt alle Dokumente zurück, bei denen der Wert von place "NYC" ist. |
db.collection.find({<field>:1,<field>:1}) |
Gibt alle Dokumente zurück, die der Abfrage entsprechen, und zeigt nur die angegebenen Felder an. |
db.users.find({status:1, item:1}) |
Gibt nur die Felder status und item sowie standardmässig _id für passende Dokumente zurück. |
db.collection.find({<field>:1,<field>:0, _id:0}) |
Schliesst das Feld _id aus den Ergebnissen aus und zeigt nur die angegebenen Felder an. |
db.users.find({status:1, item:1, _id:0}) |
Gibt passende Dokumente zurück und zeigt nur die Felder status und item ohne _id an. |
Update Operations¶
| Befehl | Beschreibung |
|---|---|
db.collection.updateOne() |
Aktualisiert ein einzelnes Dokument in der Sammlung basierend auf dem angegebenen Filter. |
db.users.updateOne({ age: 25 }, { $set: { age: 32 } }) |
Aktualisiert das Alter eines Benutzers von 25 auf 32. |
db.collection.updateMany() |
Aktualisiert alle Dokumente in der Sammlung, die dem Filter entsprechen. |
db.users.updateMany({ age: 27 }, { $inc: { age: 3 } }) |
Erhöht das Alter aller Benutzer mit dem Alter 27 um 3. |
db.collection.replaceOne() |
Ersetzt ein einzelnes Dokument in der Sammlung basierend auf dem angegebenen Filter. |
db.users.replaceOne({ name: "Kris" }, { name: "Chris" }) |
Ersetzt das erste Dokument mit dem Namen "Kris" durch ein Dokument mit dem Namen "Chris". |
Delete Operations¶
| Befehl | Beschreibung |
|---|---|
db.collection.deleteOne() |
Entfernt ein einzelnes Dokument aus der Sammlung, das dem Filter entspricht. |
db.users.deleteOne({ age: 37 }) |
Löscht das erste Dokument, bei dem das Alter 37 ist. |
db.collection.deleteMany() |
Entfernt alle Dokumente aus der Sammlung, die dem Filter entsprechen. |
db.users.deleteMany({ age: { $lt: 18 } }) |
Löscht alle Dokumente, bei denen das Alter kleiner als 18 ist. |
Operators¶
Query Operators¶
| Operator | Befehl | Beschreibung |
|---|---|---|
$eq |
db.users.find({ system: { $eq: "macOS" } }) |
Findet alle Dokumente, bei denen der Wert genau gleich "macOS" ist. |
$gt |
db.users.deleteMany({ age: { $gt: 99 } }) |
Findet alle Dokumente, bei denen der Wert grösser als 99 ist. |
$gte |
db.users.updateMany({ age: { $gte: 21 } }, { $set: { access: "valid" } }) |
Findet alle Dokumente, bei denen der Wert grösser oder gleich 21 ist, und setzt den Zugriff auf "valid". |
$in |
db.users.find({ place: { $in: ["NYC", "SF"] } }) |
Findet alle Dokumente, bei denen der Wert in der angegebenen Liste enthalten ist. |
$lt |
db.users.deleteMany({ age: { $lt: 18 } }) |
Findet alle Dokumente, bei denen der Wert kleiner als 18 ist. |
$lte |
db.users.updateMany({ age: { $lte: 17 } }, { $set: { access: "invalid" } }) |
Findet alle Dokumente, bei denen der Wert kleiner oder gleich 17 ist, und setzt den Zugriff auf "invalid". |
$ne |
db.users.find({ place: { $ne: "NYC" } }) |
Findet alle Dokumente, bei denen der Wert ungleich "NYC" ist. |
$nin |
db.users.find({ place: { $nin: ["NYC", "SF"] } }) |
Findet alle Dokumente, bei denen der Wert nicht in der angegebenen Liste enthalten ist. |
Field Operators¶
| Operator | Befehl | Beschreibung |
|---|---|---|
$inc |
db.users.updateOne({ age: 22 }, { $inc: { age: 3 } }) |
Erhöht den Wert des Feldes um den angegebenen Betrag. |
$min |
db.scores.updateOne({ _id: 1 }, { $min: { lowScore: 150 } }) |
Aktualisiert das Feld nur, wenn der angegebene Wert kleiner ist als der aktuelle Wert. |
$max |
db.scores.updateOne({ _id: 1 }, { $max: { highScore: 1000 } }) |
Aktualisiert das Feld nur, wenn der angegebene Wert grösser ist als der aktuelle Wert. |
$rename |
db.scores.updateOne({}, { $rename: { 'highScore': 'high' } }) |
Benennt ein Feld um. |
$set |
db.users.updateOne({}, { $set: { name: "valid user" } }) |
Setzt den Wert eines Feldes auf den angegebenen Wert. |
$unset |
db.users.updateOne({}, { $unset: { name: "" } }) |
Entfernt ein Feld aus einem Dokument. |
Aggregation Operations¶
| Operator | Befehl | Beschreibung |
|---|---|---|
db.collection.aggregate() |
db.users.aggregate([{ $match: { access: "valid" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } }]) |
Führt eine Aggregation durch, um Daten zu filtern, zu gruppieren und zu sortieren. |
count |
db.collection.count() |
Zählt die Anzahl der Dokumente in einer Sammlung oder Ansicht. |
distinct |
db.collection.distinct("field") |
Gibt ein Array mit eindeutigen Werten für das angegebene Feld zurück. |
mapReduce |
db.collection.mapReduce() |
Führt Map-Reduce-Operationen auf einer Sammlung durch. |
db.collection.estimatedDocumentCount() |
db.users.estimatedDocumentCount() |
Gibt die geschätzte Anzahl der Dokumente in einer Sammlung oder Ansicht zurück. |
db.collection.countDocuments() |
db.users.countDocuments({ age: { $gte: 18 } }) |
Gibt die genaue Anzahl der Dokumente zurück, die einem Filter entsprechen. |
Cheat Sheet mit allen Befehlen
Demo Basic Queries MongoDB¶
/*
BASIC MONGODB QUERIES BY
* FINDING DOCUMENTS
* FINDING THE DISTINCT FIELDS
* COUNTING THE DOCUMENTS
*/
show databases
//Switch to mflix
use mflix
/* Basic MongoDB Queries
These queries are based on the top-level (also known as root-level) fields in the documents.
*/
/*
FINDING DOCUMENTS
The most basic query in MongoDB is performed by find() on the collection.
When this method is executed without any argument, it returns all the documents in a collection.
This query calls the find() method on the collection named comments.
*/
db.comments.find()
/*
To find comments that have been added by a specific user (i.e. Lauren Carr) a name field with the value Lauren Carr
has to be added
*/
//SELECT * FROM comments WHERE name = 'Lauren Carr';
db.comments.find({"name" : "Lauren Carr"})
/*
Using findOne()
findOne() returns only one matching record.
This is very useful when you are looking to isolate a specific record.
*/
db.comments.findOne()
/*
You can capture the cursor returned by the find() in a variable and iterate through the elements.
*/
let comments = db.comments.find({"name" : "Lauren Carr"})
if (comments.hasNext) {
comments.next()
}
/*
FINDING THE DISTINCT FIELDS
The distinct() function is used to get the distinct or unique values of a field with or without query criteria.
Finding the Distinct Fields
The distinct() method is used to get unique values of a field.
*/
db.movies.distinct("rated")
/*
distinct() can also be used along with a query condition.
The following example finds all the unique ratings the films have received
that were released in 1994
*/
db.movies.distinct("rated",{year : 1994})
/*
COUNTING THE DOCUMENTS
*/
db.movies.countDocuments({})
db.movies.countDocuments({"num_mflix_comments" : 6})
Movies vs. embedded_movies¶
Antwort 1:
Die movies Collection ist referenzbasiert (normalisiert) aufgebaut – aber nur in Bezug auf die Kommentare. Die Kommentare stehen nämlich nicht direkt im Film, sondern in einer eigenen Liste (comments). Antwort 2:
Die movies Collection ist gleichzeitig auch eingebettet aufgebaut. Daten wie Schauspieler (cast) oder IMDb-Bewertungen stehen direkt im Film-Dokument drin und sind nicht ausgelagert. Antwort 3:
Der Unterschied ist der Speicherort: Eingebettet: Alle Infos (z. B. Schauspieler) stecken direkt verschachtelt im Hauptdokument. Referenziert: Die Infos sind auf verschiedene Collections verteilt und nur über eine ID verlinkt. Antwort 4: Eingebettet: Ist super schnell, weil man alles mit einem Zugriff bekommt. Aber: Ein Dokument darf nicht größer als 16 MB werden. Referenziert: Ist etwas langsamer, weil man die Daten zusammensuchen muss. Aber: Es ist flexibler und man hat unendlich Platz (z. B. für Millionen Kommentare). Antwort 5:
Man speichert einfach die ID des anderen Dokuments als Feld ab (z. B. steht im Kommentar die movie_id). Das funktioniert wie ein Link, damit man weiß, was zusammengehört.
