MongoDB ist eine dokumentenbasierte NoSQL-Datenbank. Sie speichert Daten in flexiblen JSON-ähnlichen Dokumenten (BSON) und eignet sich für Anwendungen mit sich ändernden Datenstrukturen.

MongoDB vs SQL

| Aspekt | MongoDB | SQL | |--------|---------|-----| | Datenmodell | Dokumente (JSON) | Tabellen | | Schema | Flexibel | Fest definiert | | Joins | Embedding/Referenzen | Native Joins | | Skalierung | Horizontal (Sharding) | Primär vertikal | | Transaktionen | Multi-Document (ab 4.0) | ACID nativ |

Terminologie

| SQL | MongoDB | |-----|---------| | Database | Database | | Table | Collection | | Row | Document | | Column | Field | | Index | Index |

Installation

Debian/Ubuntu

# GPG Key
curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \
    gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg

# Repository
echo "deb [signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] \
    https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
    tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Installation
apt update
apt install mongodb-org

# Starten
systemctl enable mongod
systemctl start mongod

Docker

# docker-compose.yml
version: '3.8'

services:
  mongodb:
    image: mongo:7
    container_name: mongodb
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: sicheres_passwort
    ports:
      - "27017:27017"
    volumes:
      - mongodb_data:/data/db

volumes:
  mongodb_data:

Grundlegende Befehle

Verbinden

# mongosh (MongoDB Shell)
mongosh

# Mit Authentifizierung
mongosh -u admin -p --authenticationDatabase admin

Datenbanken

// Datenbanken anzeigen
show dbs

// Datenbank wählen/erstellen
use myapp

// Aktuelle Datenbank
db

// Datenbank löschen
db.dropDatabase()

Collections

// Collections anzeigen
show collections

// Collection erstellen
db.createCollection("users")

// Collection löschen
db.users.drop()

CRUD-Operationen

Create (Insert)

// Einzelnes Dokument
db.users.insertOne({
    name: "Max Mustermann",
    email: "max@example.de",
    age: 30,
    roles: ["user", "admin"],
    address: {
        city: "Berlin",
        zip: "10115"
    },
    createdAt: new Date()
})

// Mehrere Dokumente
db.users.insertMany([
    { name: "Anna", email: "anna@example.de" },
    { name: "Peter", email: "peter@example.de" }
])

Read (Find)

// Alle Dokumente
db.users.find()

// Mit Filter
db.users.find({ name: "Max Mustermann" })

// Verschachtelte Felder
db.users.find({ "address.city": "Berlin" })

// Vergleichsoperatoren
db.users.find({ age: { $gt: 25 } })          // größer
db.users.find({ age: { $gte: 25, $lte: 35 } }) // Bereich
db.users.find({ name: { $in: ["Max", "Anna"] } }) // in Liste

// Logische Operatoren
db.users.find({
    $or: [
        { age: { $lt: 25 } },
        { roles: "admin" }
    ]
})

// Array-Abfragen
db.users.find({ roles: "admin" })           // enthält
db.users.find({ roles: { $all: ["user", "admin"] } }) // alle

// Projektion (nur bestimmte Felder)
db.users.find({}, { name: 1, email: 1, _id: 0 })

// Sortieren und Limitieren
db.users.find().sort({ name: 1 }).limit(10).skip(20)

// Einzelnes Dokument
db.users.findOne({ email: "max@example.de" })

Update

// Einzelnes Dokument
db.users.updateOne(
    { email: "max@example.de" },
    { $set: { age: 31 } }
)

// Mehrere Dokumente
db.users.updateMany(
    { age: { $lt: 18 } },
    { $set: { status: "minor" } }
)

// Update-Operatoren
db.users.updateOne(
    { _id: ObjectId("...") },
    {
        $set: { name: "Neuer Name" },
        $inc: { loginCount: 1 },
        $push: { roles: "moderator" },
        $unset: { tempField: "" },
        $currentDate: { updatedAt: true }
    }
)

// Upsert (Insert wenn nicht existiert)
db.users.updateOne(
    { email: "neu@example.de" },
    { $set: { name: "Neuer User" } },
    { upsert: true }
)

// Ersetzen
db.users.replaceOne(
    { email: "max@example.de" },
    { name: "Max", email: "max@example.de", newField: "value" }
)

Delete

// Einzelnes Dokument
db.users.deleteOne({ email: "test@example.de" })

// Mehrere Dokumente
db.users.deleteMany({ status: "inactive" })

// Alle Dokumente
db.users.deleteMany({})

Indexierung

Index erstellen

// Einfacher Index
db.users.createIndex({ email: 1 })  // 1 = aufsteigend

// Unique Index
db.users.createIndex({ email: 1 }, { unique: true })

// Compound Index
db.users.createIndex({ name: 1, createdAt: -1 })

// Text-Index
db.articles.createIndex({ title: "text", content: "text" })

// TTL Index (automatisches Löschen)
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

Index verwalten

// Indexes anzeigen
db.users.getIndexes()

// Index löschen
db.users.dropIndex("email_1")

// Query erklären
db.users.find({ email: "max@example.de" }).explain("executionStats")

Aggregation

Pipeline

db.orders.aggregate([
    // Stage 1: Filtern
    { $match: { status: "completed" } },

    // Stage 2: Gruppieren
    { $group: {
        _id: "$customerId",
        totalAmount: { $sum: "$amount" },
        orderCount: { $sum: 1 },
        avgAmount: { $avg: "$amount" }
    }},

    // Stage 3: Sortieren
    { $sort: { totalAmount: -1 } },

    // Stage 4: Limitieren
    { $limit: 10 },

    // Stage 5: Felder umbenennen
    { $project: {
        customerId: "$_id",
        totalAmount: 1,
        orderCount: 1,
        _id: 0
    }}
])

Lookup (Join)

db.orders.aggregate([
    { $lookup: {
        from: "customers",
        localField: "customerId",
        foreignField: "_id",
        as: "customer"
    }},
    { $unwind: "$customer" },
    { $project: {
        orderDate: 1,
        amount: 1,
        "customer.name": 1,
        "customer.email": 1
    }}
])

Authentifizierung

Benutzer erstellen

// Admin-Benutzer
use admin
db.createUser({
    user: "admin",
    pwd: "sicheres_passwort",
    roles: [{ role: "root", db: "admin" }]
})

// Anwendungs-Benutzer
use myapp
db.createUser({
    user: "myapp_user",
    pwd: "app_passwort",
    roles: [
        { role: "readWrite", db: "myapp" }
    ]
})

Authentifizierung aktivieren

# /etc/mongod.conf

security:
  authorization: enabled
systemctl restart mongod

Connection String

mongodb://myapp_user:app_passwort@localhost:27017/myapp

Konfiguration

mongod.conf

# /etc/mongod.conf

# Netzwerk
net:
  port: 27017
  bindIp: 127.0.0.1

# Storage
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true

# Logging
systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

# Security
security:
  authorization: enabled

# Replication (für Replica Set)
# replication:
#   replSetName: rs0

Backup

mongodump

# Alle Datenbanken
mongodump --out /backup/mongodb/$(date +%Y%m%d)

# Mit Authentifizierung
mongodump -u admin -p passwort --authenticationDatabase admin \
    --out /backup/mongodb/

# Einzelne Datenbank
mongodump -d myapp --out /backup/

# Komprimiert
mongodump --gzip --archive=/backup/mongodb.gz

mongorestore

# Wiederherstellen
mongorestore /backup/mongodb/

# Mit Authentifizierung
mongorestore -u admin -p passwort --authenticationDatabase admin \
    /backup/mongodb/

# Aus Archiv
mongorestore --gzip --archive=/backup/mongodb.gz

Replica Set

Initialisieren

// Auf Primary
rs.initiate({
    _id: "rs0",
    members: [
        { _id: 0, host: "mongo1:27017" },
        { _id: 1, host: "mongo2:27017" },
        { _id: 2, host: "mongo3:27017" }
    ]
})

// Status
rs.status()

mongod.conf

replication:
  replSetName: rs0

Connection String

mongodb://mongo1:27017,mongo2:27017,mongo3:27017/myapp?replicaSet=rs0

Node.js Integration

const { MongoClient } = require('mongodb');

const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);

async function main() {
    await client.connect();

    const db = client.db("myapp");
    const users = db.collection("users");

    // Insert
    await users.insertOne({ name: "Test", email: "test@example.de" });

    // Find
    const user = await users.findOne({ email: "test@example.de" });
    console.log(user);

    // Update
    await users.updateOne(
        { email: "test@example.de" },
        { $set: { name: "Updated" } }
    );

    // Delete
    await users.deleteOne({ email: "test@example.de" });

    await client.close();
}

main();

Monitoring

Status

// Server Status
db.serverStatus()

// Collection Stats
db.users.stats()

// Current Operations
db.currentOp()

// Profiler
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)

Prometheus

# mongodb_exporter
docker run -d -p 9216:9216 \
    bitnami/mongodb-exporter \
    --mongodb.uri="mongodb://localhost:27017"

Zusammenfassung

| Befehl | Funktion | |--------|----------| | insertOne/Many | Dokumente einfügen | | find/findOne | Dokumente suchen | | updateOne/Many | Dokumente aktualisieren | | deleteOne/Many | Dokumente löschen | | aggregate | Aggregation Pipeline | | createIndex | Index erstellen |

| Operator | Beschreibung | |----------|--------------| | $set | Feld setzen | | $inc | Inkrementieren | | $push | Array erweitern | | $gt/$lt | Vergleiche | | $in | In Liste | | $or/$and | Logisch |

| Tool | Funktion | |------|----------| | mongosh | Shell | | mongodump | Backup | | mongorestore | Restore | | mongostat | Live-Statistiken |

Fazit

MongoDB eignet sich für Anwendungen mit flexiblen Datenstrukturen. Die JSON-ähnliche Dokumentenstruktur ist entwicklerfreundlich. Horizontale Skalierung durch Sharding ist möglich. Replica Sets bieten Hochverfügbarkeit. Die Aggregation Pipeline ermöglicht komplexe Datenanalysen. Für streng relationale Daten bleibt SQL oft die bessere Wahl.