W3docs

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?

SituationGute Wahl?
Sich schnell ändernde Datenstrukturen (Prototypen, APIs)Ja
Hierarchische / verschachtelte DatenJa
Komplexe mehrtabellige JOIN-AbfragenSQL bevorzugen
Starke ACID-Transaktionen über viele TabellenSQL bevorzugen
Volltextsuche in großem MaßstabMit 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:7

Dies 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 pymongo

Um 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.3

Verbindung 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:

OptionBeispielZweck
authSourceauthSource=adminDatenbank für die Authentifizierung
replicaSetreplicaSet=rs0Verbindung zu einem Replica Set
tls=truetls=trueTLS/SSL aktivieren
serverSelectionTimeoutMSserverSelectionTimeoutMS=5000Timeout 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 inserted

Grundlegende 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:

OperatorBedeutung
$eqGleich (Standard bei {"field": value})
$neUngleich
$gt / $gteGrößer als / größer als oder gleich
$lt / $lteKleiner als / kleiner als oder gleich
$inWert ist in einer Liste
$ninWert 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:

OperatorWirkung
$setEin oder mehrere Felder setzen
$unsetEin Feld entfernen
$incEin numerisches Feld inkrementieren
$pushEinen Wert an ein array-Feld anhängen
$pullEinen 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 database

Lö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:

Was this page helpful?