MongoDB – Erste Schritte
MongoDB installieren, mit PyMongo verbinden und grundlegende CRUD-Operationen in Python durchführen – mit klaren, funktionierenden Beispielen.
Dieses Kapitel stellt MongoDB vor und zeigt, wie man es aus Python heraus mithilfe des PyMongo-Treibers verwendet. Am Ende werden Sie MongoDB installiert haben, eine funktionierende Verbindung besitzen und ein klares Bild davon haben, wie man Dokumente einfügt, abfragt, aktualisiert und löscht.
Was ist MongoDB?
MongoDB ist eine Dokumentendatenbank – eine Art NoSQL-Datenbank, die Datensätze als JSON-ähnliche Dokumente statt als Zeilen und Spalten speichert. Jedes Dokument ist ein eigenständiges Objekt, das verschachtelte Felder und arrays enthalten kann. Das macht es zu einer natürlichen Wahl für Daten, die sich nicht sauber in ein festes Schema fügen.
Wesentliche Merkmale:
- Schema-flexibel. Zwei Dokumente in derselben Collection können völlig unterschiedliche Felder haben.
- Leistungsstarke Abfragesprache. Filtern, projizieren, sortieren, begrenzen und aggregieren mit einem einzigen Treiber-Aufruf.
- Horizontale Skalierbarkeit. Eingebautes Sharding und Replica Sets bewältigen große Datenmengen und hohe Verfügbarkeit.
- JSON-nativ. Dokumente werden als BSON (Binary JSON) gespeichert, sodass Python-Dicts direkt auf MongoDB-Dokumente abgebildet werden.
Wann MongoDB einer relationalen Datenbank vorziehen?
| Situation | Gute Wahl? |
|---|---|
| Sich schnell ändernde Datenstrukturen (Prototypen, APIs) | Ja |
| Hierarchische / verschachtelte Daten | Ja |
Komplexe mehrtabellige JOIN-Abfragen | SQL bevorzugen |
Starke ACID-Transaktionen über viele Tabellen | SQL bevorzugen |
| Volltextsuche in großem Maßstab | Mit Elasticsearch kombinieren |
MongoDB installieren
Option 1 – Lokale Installation
Laden Sie den MongoDB Community Server von mongodb.com/try/download/community herunter, wählen Sie Ihr Betriebssystem und folgen Sie dem Installationsprogramm. Starten Sie dann den Server:
# macOS / Linux
mongod --dbpath /data/db
# Windows (PowerShell, run as Administrator)
mongod --dbpath "C:\data\db"Überprüfen Sie, ob MongoDB läuft, indem Sie ein zweites Terminal öffnen und ausführen:
mongosh --eval "db.adminCommand('ping')"Erwartete Ausgabe:
{ ok: 1 }Option 2 – Docker (schnellste Methode für die Entwicklung)
Wenn Sie Docker installiert haben, können Sie die lokale Installation vollständig überspringen:
docker run -d --name mongo -p 27017:27017 mongo:7Dies lädt das offizielle MongoDB-7-Image herunter und exponiert Port 27017 auf Ihrem Rechner. Stoppen Sie es mit docker stop mongo.
Option 3 – MongoDB Atlas (Cloud)
Atlas ist der vollständig verwaltete Cloud-Dienst von MongoDB mit einem kostenlosen Tarif. Nach der Registrierung kopieren Sie den Connection String aus dem Dashboard – er sieht so aus:
mongodb+srv://username:[email protected]/Sie können diesen URI überall verwenden, wo in diesem Kapitel mongodb://localhost:27017/ steht.
Den PyMongo-Treiber installieren
PyMongo ist der offizielle Python-Treiber für MongoDB. Installieren Sie ihn mit pip:
pip install pymongoUm MongoDB Atlas zu verwenden, installieren Sie auch die Extras, die den DNS-Resolver enthalten:
pip install "pymongo[srv]"Überprüfen Sie die Installation:
import pymongo
print(pymongo.version)
# e.g. 4.7.3Verbindung zu MongoDB herstellen
MongoClient ist der Einstiegspunkt für alle Treiber-Operationen. Erstellen Sie einen Client pro Anwendung und verwenden Sie ihn wieder – der Client verwaltet einen internen Connection Pool.
from pymongo import MongoClient
# Local server with default host and port
client = MongoClient("mongodb://localhost:27017/")
# Verify connectivity (raises ConnectionFailure if the server is unreachable)
client.admin.command("ping")
print("Connected successfully")Für Produktionscode sollten Sie Verbindungsfehler immer explizit behandeln:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient("mongodb://localhost:27017/", serverSelectionTimeoutMS=3000)
try:
client.admin.command("ping")
print("Connected to MongoDB")
except ConnectionFailure as e:
print("Connection failed:", e)Format des Connection Strings
mongodb://[username:password@]host[:port][/database][?options]Häufige Optionen:
| Option | Beispiel | Zweck |
|---|---|---|
authSource | authSource=admin | Datenbank für die Authentifizierung |
replicaSet | replicaSet=rs0 | Verbindung zu einem Replica Set |
tls=true | tls=true | TLS/SSL aktivieren |
serverSelectionTimeoutMS | serverSelectionTimeoutMS=5000 | Timeout für die Serverauswahl |
Datenbanken und Collections
MongoDB organisiert Daten in einer zweistufigen Hierarchie:
- Eine Datenbank gruppiert verwandte Collections (ähnlich wie ein SQL-Schema oder eine SQL-Datenbank).
- Eine Collection enthält Dokumente (ähnlich wie eine SQL-Tabelle, aber ohne festes Schema).
Beide werden lazy erstellt – sie entstehen beim ersten Einfügen eines Dokuments. Sie führen niemals CREATE DATABASE oder CREATE TABLE aus.
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
# Reference a database (not yet created on disk)
db = client["mystore"]
# Reference a collection inside it (also not yet on disk)
products = db["products"]
# The database and collection are created when the first document is insertedGrundlegende CRUD-Operationen
Die folgenden Beispiele bauen aufeinander auf. Führen Sie sie der Reihe nach aus, wenn Sie interaktiv mitmachen.
Erstellen – Dokumente einfügen
Verwenden Sie insert_one() für ein einzelnes Dokument und insert_many() für einen Stapel:
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
db = client["mystore"]
products = db["products"]
# Insert a single document
result = products.insert_one({
"name": "Laptop",
"brand": "Acme",
"price": 999.99,
"in_stock": True
})
print("Inserted id:", result.inserted_id)
# Insert multiple documents at once
new_products = [
{"name": "Mouse", "brand": "Acme", "price": 29.99, "in_stock": True},
{"name": "Keyboard", "brand": "Acme", "price": 79.99, "in_stock": False},
{"name": "Monitor", "brand": "Zeta", "price": 349.99, "in_stock": True},
]
batch_result = products.insert_many(new_products)
print("Inserted ids:", batch_result.inserted_ids)MongoDB fügt jedem Dokument automatisch ein _id-Feld (vom Typ ObjectId) hinzu, wenn Sie keines angeben. Dieses Feld ist der Primärschlüssel und innerhalb einer Collection stets eindeutig.
Lesen – Dokumente abfragen
find_one() gibt das erste übereinstimmende Dokument zurück (oder None). find() gibt einen Cursor zurück, über den Sie iterieren können.
# Retrieve one document (no filter = the first document in natural order)
doc = products.find_one()
print(doc)
# Retrieve all documents in the collection
for p in products.find():
print(p["name"], "-", p["price"])
# Filter: products that are in stock
for p in products.find({"in_stock": True}):
print(p["name"])
# Projection: return only name and price (exclude _id)
for p in products.find({}, {"_id": 0, "name": 1, "price": 1}):
print(p)Abfrageoperatoren
Die Abfragesprache von MongoDB verwendet Operatoren mit dem Präfix $:
# Products cheaper than £100
cheap = products.find({"price": {"$lt": 100}})
# In-stock products from brand "Acme" or "Zeta"
multi = products.find({
"in_stock": True,
"brand": {"$in": ["Acme", "Zeta"]}
})
# Price between 50 and 500 (inclusive)
range_q = products.find({"price": {"$gte": 50, "$lte": 500}})Häufige Vergleichsoperatoren:
| Operator | Bedeutung |
|---|---|
$eq | Gleich (Standard bei {"field": value}) |
$ne | Ungleich |
$gt / $gte | Größer als / größer als oder gleich |
$lt / $lte | Kleiner als / kleiner als oder gleich |
$in | Wert ist in einer Liste |
$nin | Wert ist nicht in einer Liste |
Aktualisieren – Dokumente ändern
update_one() ändert das erste übereinstimmende Dokument. update_many() ändert alle Treffer. Verwenden Sie immer den $set-Operator, um bestimmte Felder zu ändern – ohne ihn ersetzen Sie das gesamte Dokument.
# Update a single document: change the price of "Mouse"
update_result = products.update_one(
{"name": "Mouse"}, # filter
{"$set": {"price": 24.99}} # update
)
print("Matched:", update_result.matched_count,
"Modified:", update_result.modified_count)
# Mark all Acme products as in stock
products.update_many(
{"brand": "Acme"},
{"$set": {"in_stock": True}}
)
# Increment a field value
products.update_one(
{"name": "Laptop"},
{"$inc": {"price": -50}} # reduce price by 50
)Häufige Update-Operatoren:
| Operator | Wirkung |
|---|---|
$set | Ein oder mehrere Felder setzen |
$unset | Ein Feld entfernen |
$inc | Ein numerisches Feld inkrementieren |
$push | Einen Wert an ein array-Feld anhängen |
$pull | Einen Wert aus einem array-Feld entfernen |
Löschen – Dokumente entfernen
delete_one() entfernt das erste übereinstimmende Dokument. delete_many() entfernt alle Treffer.
# Remove a single document
del_result = products.delete_one({"name": "Keyboard"})
print("Deleted count:", del_result.deleted_count)
# Remove all out-of-stock items
products.delete_many({"in_stock": False})
# Confirm what is left
print("Remaining products:")
for p in products.find({}, {"_id": 0, "name": 1}):
print(" -", p["name"])Häufige Fallstricke
Lazy-Erstellung kann Tippfehler verbergen
Da MongoDB Datenbanken und Collections bei Bedarf erstellt, erzeugt ein Tippfehler stillschweigend eine zweite, leere Datenbank, anstatt einen Fehler auszulösen:
# Intended: client["mystore"] Actual: client["mystoree"]
db = client["mystoree"] # no error, but your data goes to the wrong databaseLösung: Definieren Sie Datenbank- und Collection-Namen als Konstanten auf Modulebene:
DB_NAME = "mystore"
COL_NAME = "products"
db = client[DB_NAME]
products = db[COL_NAME]Verbindungsfehler treten erst bei der ersten Operation auf
MongoClient() ist auch dann erfolgreich, wenn MongoDB nicht läuft. Der Fehler tritt erst bei einer tatsächlichen Anfrage auf. Verwenden Sie serverSelectionTimeoutMS und einen ping-Check beim Start (wie im Verbindungsabschnitt oben gezeigt), um schnell zu scheitern.
Fehlendes $set ersetzt das gesamte Dokument
# WRONG — replaces the whole document with just {"price": 24.99}
products.update_one({"name": "Mouse"}, {"price": 24.99})
# CORRECT — only changes the price field
products.update_one({"name": "Mouse"}, {"$set": {"price": 24.99}})find() gibt einen Cursor zurück, keine Liste
Ein Cursor ist lazy – Dokumente werden erst vom Server abgerufen, wenn Sie darüber iterieren. Wenn Sie eine einfache Liste benötigen, konvertieren Sie explizit:
all_products = list(products.find())Seien Sie bei großen Collections vorsichtig: Alles auf einmal in den Speicher zu laden, kann den RAM erschöpfen.
Was kommt als Nächstes
Dieses Kapitel hat die Grundlagen abgedeckt. Die restliche Python-MongoDB-Reihe vertieft jedes Thema:
- MongoDB Create Database – wie Lazy-Erstellung funktioniert und wie man überprüft, ob eine Datenbank existiert.
- MongoDB Create Collection – Optionen zur Collection-Erstellung und Validierungsschemata.
- MongoDB Insert –
insert_one(),insert_many()und der Umgang mit Duplicate-Key-Fehlern. - MongoDB Find – Projektionen, Cursor und Sortierung.
- MongoDB Query – vollständige Referenz der Abfrageoperatoren.
- MongoDB Update –
update_one(),update_many(),upsertund array-Operatoren. - MongoDB Delete – sichere Löschmuster und
drop(). - MongoDB Sort – Ein- und Mehrfeldersortierung.
- MongoDB Limit – Paginierung mit
limit()undskip(). - MongoDB Drop Collection – eine Collection vollständig entfernen.