MongoDB ist eine dokumentenorientierte NoSQL-Datenbank. Sie speichert Daten in flexiblen JSON-ähnlichen Dokumenten statt in starren Tabellen.
Vorteile von MongoDB
NoSQL vs. SQL
| Feature | MongoDB | SQL | |---------|---------|-----| | Schema | Flexibel | Starr | | Datenformat | JSON/BSON | Tabellen | | Skalierung | Horizontal | Vertikal | | Joins | Embedded/Lookup | Native | | Transaktionen | Seit 4.0 | Native |
Anwendungsfälle
- Content Management Systeme
- Echtzeit-Analytik
- IoT-Daten
- Kataloge und Inventar
- Mobile Apps
- Gaming (Leaderboards, Sessions)Installation
Debian/Ubuntu
# GPG-Key
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb.gpg
# Repository
echo "deb [signed-by=/usr/share/keyrings/mongodb.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list
# Installieren
apt update
apt install mongodb-org
# Starten
systemctl enable --now mongodDocker
docker run -d \
--name mongodb \
-p 27017:27017 \
-v mongodb-data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:7Konfiguration
mongod.conf
# /etc/mongod.conf
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 127.0.0.1
security:
authorization: enabledAuthentifizierung aktivieren
# Erst Admin-User erstellen (ohne Auth)
mongosh
use admin
db.createUser({
user: "admin",
pwd: "securePassword",
roles: ["root"]
})
# Dann in mongod.conf:
# security:
# authorization: enabled
# Service neustarten
systemctl restart mongodMongoDB Shell (mongosh)
Verbinden
# Lokal
mongosh
# Mit Authentifizierung
mongosh -u admin -p password --authenticationDatabase admin
# Remote
mongosh "mongodb://user:password@hostname:27017/database"Grundbefehle
// Datenbanken anzeigen
show dbs
// Datenbank wechseln/erstellen
use mydb
// Collections anzeigen
show collections
// Hilfe
help
db.help()CRUD-Operationen
Dokument einfügen
// Ein Dokument
db.users.insertOne({
name: "Max Mustermann",
email: "max@example.com",
age: 30,
tags: ["admin", "developer"],
address: {
city: "Berlin",
zip: "10115"
},
createdAt: new Date()
})
// Mehrere Dokumente
db.users.insertMany([
{ name: "Anna", email: "anna@example.com", age: 25 },
{ name: "Tom", email: "tom@example.com", age: 35 }
])Dokumente abfragen
// Alle
db.users.find()
// Mit Filter
db.users.find({ name: "Max Mustermann" })
// Vergleichsoperatoren
db.users.find({ age: { $gt: 25 } }) // Größer als
db.users.find({ age: { $gte: 25 } }) // Größer oder gleich
db.users.find({ age: { $lt: 30 } }) // Kleiner als
db.users.find({ age: { $ne: 25 } }) // Ungleich
db.users.find({ age: { $in: [25, 30] } }) // In Array
// Logische Operatoren
db.users.find({ $and: [{ age: { $gt: 20 } }, { age: { $lt: 30 } }] })
db.users.find({ $or: [{ name: "Max" }, { name: "Anna" }] })
// Nested Documents
db.users.find({ "address.city": "Berlin" })
// Array enthält
db.users.find({ tags: "admin" })
// Projektion (Felder auswählen)
db.users.find({}, { name: 1, email: 1, _id: 0 })
// Sortieren und Limitieren
db.users.find().sort({ age: -1 }).limit(10)Dokumente aktualisieren
// Ein Dokument
db.users.updateOne(
{ name: "Max Mustermann" },
{ $set: { age: 31 } }
)
// Mehrere Dokumente
db.users.updateMany(
{ age: { $lt: 30 } },
{ $set: { status: "young" } }
)
// Upsert (Insert wenn nicht existiert)
db.users.updateOne(
{ email: "new@example.com" },
{ $set: { name: "New User" } },
{ upsert: true }
)
// Operatoren
db.users.updateOne(
{ name: "Max" },
{
$set: { status: "active" }, // Feld setzen
$unset: { temporary: "" }, // Feld entfernen
$inc: { loginCount: 1 }, // Inkrementieren
$push: { tags: "verified" }, // Array erweitern
$pull: { tags: "temporary" } // Aus Array entfernen
}
)Dokumente löschen
// Ein Dokument
db.users.deleteOne({ name: "Test" })
// Mehrere Dokumente
db.users.deleteMany({ status: "inactive" })
// Alle Dokumente
db.users.deleteMany({})
// Collection löschen
db.users.drop()Indizes
Index erstellen
// Einfacher Index
db.users.createIndex({ email: 1 })
// Zusammengesetzter Index
db.users.createIndex({ name: 1, age: -1 })
// Unique Index
db.users.createIndex({ email: 1 }, { unique: true })
// Text Index (Volltextsuche)
db.articles.createIndex({ title: "text", content: "text" })
// TTL Index (automatisches Löschen)
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })Indizes verwalten
// Indizes anzeigen
db.users.getIndexes()
// Index löschen
db.users.dropIndex("email_1")
// Alle Indizes löschen (außer _id)
db.users.dropIndexes()Query analysieren
// Execution Plan
db.users.find({ email: "max@example.com" }).explain("executionStats")Aggregation Pipeline
Grundstruktur
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
])Wichtige Stages
// $match - Filtern
{ $match: { status: "active" } }
// $group - Gruppieren
{ $group: {
_id: "$category",
count: { $sum: 1 },
avgPrice: { $avg: "$price" },
totalRevenue: { $sum: "$revenue" }
}}
// $sort - Sortieren
{ $sort: { count: -1 } }
// $limit / $skip - Pagination
{ $skip: 20 }
{ $limit: 10 }
// $project - Felder auswählen/transformieren
{ $project: {
name: 1,
fullName: { $concat: ["$firstName", " ", "$lastName"] },
year: { $year: "$createdAt" }
}}
// $lookup - Join
{ $lookup: {
from: "orders",
localField: "_id",
foreignField: "customerId",
as: "orders"
}}
// $unwind - Array auflösen
{ $unwind: "$tags" }Praktisches Beispiel
// Umsatz pro Monat
db.orders.aggregate([
{ $match: {
createdAt: { $gte: ISODate("2024-01-01") }
}},
{ $group: {
_id: { $month: "$createdAt" },
revenue: { $sum: "$total" },
orders: { $sum: 1 }
}},
{ $sort: { _id: 1 } }
])Replikation (Replica Set)
Replica Set initialisieren
// Auf Primary
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1 }
]
})Node-Konfiguration
# mongod.conf
replication:
replSetName: "rs0"Status prüfen
rs.status()
rs.conf()
rs.isMaster()Sharding
Sharded Cluster
┌─────────────┐
│ mongos │ (Router)
└─────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Shard 1 │ │ Shard 2 │ │ Shard 3 │
│ (RS) │ │ (RS) │ │ (RS) │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└─────────────────┼─────────────────┘
▼
┌─────────────┐
│ Config RS │
└─────────────┘Sharding aktivieren
// Datenbank für Sharding aktivieren
sh.enableSharding("mydb")
// Collection sharden
sh.shardCollection("mydb.users", { region: 1 })
// Status
sh.status()Backup und Restore
mongodump / mongorestore
# Alle Datenbanken
mongodump --out /backup/$(date +%Y%m%d)
# Eine Datenbank
mongodump --db mydb --out /backup/
# Mit Authentifizierung
mongodump -u admin -p password --authenticationDatabase admin --db mydb
# Restore
mongorestore /backup/mydb/
mongorestore --db mydb /backup/mydb/Einzelne Collection
# Export als JSON
mongoexport --db mydb --collection users --out users.json
# Import
mongoimport --db mydb --collection users --file users.jsonSicherheit
Benutzer erstellen
use mydb
db.createUser({
user: "appuser",
pwd: "password",
roles: [
{ role: "readWrite", db: "mydb" }
]
})Rollen
| Rolle | Berechtigung | |-------|--------------| | read | Nur lesen | | readWrite | Lesen und Schreiben | | dbAdmin | Index- und Schema-Management | | userAdmin | Benutzerverwaltung | | dbOwner | Vollzugriff auf Datenbank | | root | Vollzugriff auf alles |
Netzwerk-Sicherheit
# mongod.conf
net:
bindIp: 127.0.0.1,192.168.1.10
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pemMonitoring
Server-Status
db.serverStatus()
db.stats()
db.collection.stats()Current Operations
db.currentOp()
db.killOp(opId)Profiling
// Profiler aktivieren
db.setProfilingLevel(2) // 0=off, 1=slow, 2=all
// Profiling-Daten
db.system.profile.find().sort({ ts: -1 }).limit(10)Troubleshooting
Logs
tail -f /var/log/mongodb/mongod.logVerbindungsprobleme
# Port prüfen
ss -tlnp | grep 27017
# Verbindung testen
mongosh --eval "db.adminCommand('ping')"Performance
// Langsame Queries
db.setProfilingLevel(1, { slowms: 100 })
// Index-Nutzung prüfen
db.collection.find({...}).explain("executionStats")Zusammenfassung
| Befehl | Funktion | |--------|----------| | find() | Dokumente suchen | | insertOne/Many() | Einfügen | | updateOne/Many() | Aktualisieren | | deleteOne/Many() | Löschen | | aggregate() | Aggregation Pipeline | | createIndex() | Index erstellen |
| Operator | Funktion | |----------|----------| | $gt, $lt, $gte, $lte | Vergleiche | | $in, $nin | In/Nicht in Array | | $and, $or, $not | Logisch | | $set, $unset | Felder setzen/entfernen | | $push, $pull | Array-Operationen | | $inc | Inkrementieren |
| Port | Dienst | |------|--------| | 27017 | MongoDB | | 27018 | Sharding (Shard) | | 27019 | Sharding (Config) |
Fazit
MongoDB bietet mit seinem flexiblen Dokumentenmodell große Vorteile für Anwendungen mit wechselnden Anforderungen. Die Aggregation Pipeline ermöglicht komplexe Datenanalysen. Für Skalierung stehen Replica Sets und Sharding zur Verfügung. Die JSON-ähnliche Syntax macht den Einstieg leicht. Für Transaktionen über mehrere Dokumente sind relationale Datenbanken oft besser geeignet, aber MongoDB deckt viele moderne Anwendungsfälle hervorragend ab.