14 Neuerungen in MongoDB Version 6.0

MongoDB 6.0, veröffentlicht im Juli 2022, baute konsequent auf den Zeitreihen-Fähigkeiten von Version 5.0 auf. Während 5.0 die Infrastruktur für Zeitreihendaten schuf, lieferte 6.0 die Werkzeuge, um mit diesen Daten effektiv zu arbeiten. Der Fokus lag auf der Aggregation-Pipeline – MongoDB’s mächtigstem Werkzeug für Datenverarbeitung. Eine Flut neuer Stages und Operatoren adressierte typische Probleme bei der Arbeit mit Zeitreihen: fehlende Datenpunkte, Lücken in Sequenzen, Interpolation und statistische Analysen.

Neben den Analytics-Features brachte 6.0 operative Verbesserungen für große Deployments: effizientere Change Streams, zentrale Clusterkonfiguration und optimiertes Sharding. Die Version festigte MongoDB’s Position nicht nur als Dokumentendatenbank, sondern als vollwertige Analytics-Plattform.

14.1 Lücken füllen: $densify und $fill

Zeitreihendaten sind selten perfekt. Sensoren fallen aus, Netzwerke haben Unterbrechungen, Logs gehen verloren. Das Resultat sind Lücken in Datensequenzen – fehlende Zeitstempel, wo Messungen sein sollten. Für Analysen und Visualisierungen sind solche Lücken problematisch. Ein Chart mit fehlenden Datenpunkten sieht unvollständig aus, statistische Berechnungen können verzerrt werden.

Die neue Stage $densify löst dieses Problem systematisch. Sie nimmt eine Sequenz von Dokumenten und füllt Lücken basierend auf definierten Regeln. Ein klassisches Szenario: Temperaturmessungen alle 10 Minuten, aber der Sensor war zwischen 14:20 und 14:40 offline. $densify fügt die fehlenden Zeitstempel ein, entweder mit Standardwerten oder durch Interpolation aus umgebenden Datenpunkten.

db.temperature.aggregate([
  { $densify: {
      field: "timestamp",
      range: {
        step: 10,
        unit: "minute",
        bounds: "full"
      }
  }},
  { $set: {
      temperature: { 
        $ifNull: ["$temperature", { $avg: ["$prevTemp", "$nextTemp"] }]
      }
  }}
])

Diese Pipeline densifiziert die Zeitreihe auf 10-Minuten-Schritte über den gesamten Bereich. Fehlende temperature-Werte werden durch den Durchschnitt der vorherigen und nächsten Messung interpoliert. Das Resultat ist eine lückenlose Sequenz, ideal für Charts oder weitere Analysen.

Die $fill-Stage ist der semantische Partner zu $densify. Während $densify fehlende Dokumente hinzufügt, füllt $fill fehlende oder null-Werte in bestehenden Dokumenten. Dies ist nützlich, wenn Dokumente existieren, aber einzelne Felder fehlen.

db.sales.aggregate([
  { $fill: {
      sortBy: { date: 1 },
      output: {
        revenue: { method: "locf" },  // Last Observation Carried Forward
        quantity: { method: "linear" } // Lineare Interpolation
      }
  }}
])

Diese Pipeline füllt fehlende revenue-Werte mit dem letzten bekannten Wert (LOCF – eine gängige Methode in Finanz-Zeitreihen) und interpoliert quantity linear zwischen bekannten Punkten. Die sortBy-Option stellt sicher, dass die Reihenfolge korrekt ist, bevor Werte vorwärts propagiert oder interpoliert werden.

Die Kombination von $densify und $fill ist mächtig. $densify stellt sicher, dass alle Zeitpunkte existieren, $fill stellt sicher, dass alle Felder Werte haben. Zusammen transformieren sie unvollständige Rohdaten in saubere, analysefreundliche Datensätze.

14.2 Top-N und Bottom-N: Neue Ranking-Operatoren

Ranking-Operationen – “die Top 10”, “die schlechtesten 5” – sind in Analytics allgegenwärtig. Vor Version 6.0 erforderte dies umständliche Kombinationen von $sort, $limit und $group. Die neuen Operatoren $top, $bottom, $topN und $bottomN machen dies explizit und effizienter.

// Top 3 Verkäufer pro Region
db.sales.aggregate([
  { $group: {
      _id: "$region",
      topSellers: { 
        $topN: {
          n: 3,
          sortBy: { revenue: -1 },
          output: { name: "$salesperson", revenue: "$revenue" }
        }
      }
  }}
])

Diese Pipeline gruppiert nach Region und extrahiert pro Gruppe die drei umsatzstärksten Verkäufer. Der $topN-Operator macht dies in einer Operation, statt erst zu sortieren, dann zu limitieren. Das ist nicht nur syntaktisch eleganter, sondern auch performanter – MongoDB kann die Top-N intern optimiert berechnen, ohne das gesamte Resultset zu sortieren.

Die $firstN und $lastN-Operatoren adressieren einen verwandten Use-Case: die ersten oder letzten N Elemente einer Sequenz. Dies ist besonders nützlich für Zeitreihen. “Die ersten 5 Messungen nach einem Event” oder “die letzten 10 Transaktionen eines Users” sind typische Queries.

// Letzte 5 Logins pro User
db.logins.aggregate([
  { $sort: { timestamp: -1 } },
  { $group: {
      _id: "$userId",
      recentLogins: { 
        $firstN: {
          n: 5,
          input: { timestamp: "$timestamp", ip: "$ip" }
        }
      }
  }}
])

Diese Operatoren füllen eine Lücke in MongoDBs Aggregation-Toolbox. Vor 6.0 waren solche Queries möglich, aber unelegant. Jetzt sind sie idiomatisch und performant.

14.3 Dokumenten-Literale und Array-Sortierung

Die $documents-Stage ist ungewöhnlich – sie fügt literale Dokumente direkt in die Pipeline ein, ohne sie aus einer Collection zu lesen. Auf den ersten Blick scheint dies nutzlos: Warum Daten in die Query schreiben, statt sie aus der Datenbank zu lesen?

Der Use-Case ist spezifisch: Tests, Prototyping und Self-Joins. Für Tests kann man eine Pipeline mit synthetischen Daten füttern, ohne Test-Collections anlegen zu müssen. Für Self-Joins – etwa “vergleiche Verkäufe mit Durchschnitt der letzten 12 Monate” – kann man Referenzdaten inline definieren.

db.sales.aggregate([
  { $documents: [
      { month: "Q1", target: 100000 },
      { month: "Q2", target: 120000 },
      { month: "Q3", target: 110000 },
      { month: "Q4", target: 150000 }
  ]},
  { $lookup: {
      from: "actual_sales",
      localField: "month",
      foreignField: "quarter",
      as: "actuals"
  }},
  { $project: {
      month: 1,
      target: 1,
      actual: { $sum: "$actuals.revenue" },
      variance: { $subtract: [{ $sum: "$actuals.revenue" }, "$target"] }
  }}
])

Diese Pipeline startet mit literalen Quartalszielen, joinst sie mit tatsächlichen Verkäufen und berechnet Abweichungen. Die Targets sind klein und ändern sich selten – sie im Code zu definieren ist pragmatischer als eine separate Collection.

Der $sortArray-Operator ist simpler: Er sortiert Arrays innerhalb von Dokumenten. Vor 6.0 musste man dafür in die Anwendungslogik wechseln oder umständliche $map-Konstrukte bauen. Jetzt ist es eine Zeile:

db.products.aggregate([
  { $project: {
      name: 1,
      sortedReviews: { 
        $sortArray: { 
          input: "$reviews", 
          sortBy: { rating: -1 } 
        }
      }
  }}
])

Dies sortiert das reviews-Array jedes Produkts nach Rating, höchste zuerst. Nützlich für Präsentation oder wenn die weitere Pipeline auf sortierte Arrays angewiesen ist.

14.4 Sharding-Insights: $shardedDataDistribution

Sharded Clusters sind komplex, und Datenverteilung über Shards ist oft intransparent. Ist die Last gleichmäßig? Gibt es Hotspots? Welcher Shard hält wieviel Daten? Vor 6.0 erforderte dies Monitoring-Tools oder manuelles Abfragen von Server-Status-Commands.

Die neue Stage $shardedDataDistribution macht Verteilungsinformationen direkt in der Aggregation-Pipeline verfügbar:

db.orders.aggregate([
  { $shardedDataDistribution: {} }
])

Das Resultat ist eine Liste von Shards mit Details: Anzahl der Chunks, Datengröße, Anzahl der Dokumente. Dies erlaubt Analysen direkt in der Datenbank:

db.orders.aggregate([
  { $shardedDataDistribution: {} },
  { $group: {
      _id: null,
      totalShards: { $sum: 1 },
      avgSize: { $avg: "$shardInfo.sizeBytes" },
      maxSize: { $max: "$shardInfo.sizeBytes" },
      minSize: { $min: "$shardInfo.sizeBytes" }
  }}
])

Diese Pipeline berechnet Statistiken über die Verteilung. Ein hohes Verhältnis maxSize / minSize indiziert ungleiche Verteilung – ein Hinweis, dass der Shard Key suboptimal sein könnte.

Für Administratoren großer Clusters ist dies wertvoll. Statt externe Tools zu bemühen, kann man Verteilung direkt queryen und etwa automatische Alerts bei Ungleichgewicht triggern.

14.5 Operative Verbesserungen: Change Streams und Cluster-Parameter

Change Streams, eingeführt in MongoDB 3.6, erlauben Echtzeit-Monitoring von Datenänderungen. Anwendungen können auf Inserts, Updates oder Deletes reagieren, ähnlich Database-Triggers in SQL. Die Implementierung war ressourcenintensiv – jeder Change Stream hielt Verbindungen offen und konsumierte RAM.

Version 6.0 optimierte dies erheblich. Die interne Architektur wurde umgebaut, um Overhead zu reduzieren. Mehrere Change Streams auf derselben Collection teilen nun Ressourcen, statt isoliert zu operieren. Der Memory-Footprint sank um 30-50% in typischen Szenarien. Für Anwendungen mit hunderten oder tausenden aktiven Streams – etwa Microservice-Architekturen, wo jeder Service Changes monitort – ist dies ein signifikanter Gewinn.

Die Einführung von Cluster-weiten Server-Parametern vereinfachte das Management großer Deployments. Bisher mussten Parameter wie slowOpThresholdMs oder maxIncomingConnections auf jedem Knoten individuell gesetzt werden. In einem Replica Set mit drei Knoten war dies dreimaliger Aufwand. In einem Sharded Cluster mit Dutzenden Shards wurde es zum operativen Albtraum.

Version 6.0 führte Cluster Parameter ein – Einstellungen, die zentral definiert und automatisch auf alle Knoten propagiert werden:

db.adminCommand({
  setClusterParameter: {
    slowOpThresholdMs: { value: 500 }
  }
})

Diese Command setzt den Threshold auf allen Knoten des Clusters. Änderungen sind sofort aktiv, kein Rolling Restart nötig. Dies vereinfacht nicht nur manuelles Management, sondern auch automatisierte Konfiguration via Infrastructure-as-Code.

14.6 Sharding-Optimierung: Größere Chunks

Eine subtile aber wichtige Änderung betraf die Standard-Chunk-Größe in Sharded Clusters. Chunks sind die Einheiten, in die MongoDB Daten aufteilt und auf Shards verteilt. Bisher waren Chunks 64 MB groß. Erreichte ein Chunk diese Größe, teilte MongoDB ihn in zwei 32-MB-Chunks.

Diese Größe stammte aus einer Ära, wo typische Deployments Hunderte Gigabytes verwalten. Moderne Deployments handhaben Terabytes oder Petabytes. Bei solchen Skalen führen 64-MB-Chunks zu Millionen von Chunks. Jeder Chunk bedeutet Metadaten, die Config-Server verwalten müssen. Die Balancing-Logik muss mehr Chunks bewegen.

Version 6.0 erhöhte die Standard-Chunk-Größe auf 128 MB. Dies halbiert die Anzahl der Chunks bei gleicher Datenmenge. Weniger Chunks bedeuten weniger Metadaten-Overhead, weniger Splits, effizienteres Balancing. In Benchmarks mit Multi-Terabyte-Datasets zeigten sich messbare Performance-Verbesserungen beim Sharding und Rebalancing.

Die Änderung ist rückwärtskompatibel – bestehende Clusters mit 64-MB-Chunks funktionieren weiter. Neue Chunks verwenden 128 MB. Administratoren können die Größe auch manuell anpassen, falls andere Werte sinnvoller sind.

14.7 Sicherheit: Verschlüsselte Audit-Logs

Für MongoDB Enterprise wurde eine oft nachgefragte Funktion hinzugefügt: Verschlüsselung von Audit-Logs. Audit-Logs protokollieren sicherheitsrelevante Ereignisse – Logins, Zugriffe auf sensible Collections, Permission-Changes. Diese Logs selbst enthalten oft sensible Informationen.

Bisher waren Audit-Logs im Klartext auf Disk. Für Compliance-intensive Branchen wie Finanz oder Healthcare war dies problematisch. Logs müssen geschützt werden wie die Daten selbst. Version 6.0 erlaubt transparente Verschlüsselung der Audit-Logs mittels KMS (Key Management Service):

auditLog:
  destination: file
  format: JSON
  path: /var/log/mongodb/audit.log
  encryption:
    kmip:
      serverName: kmip.example.com
      port: 5696

Diese Konfiguration verschlüsselt Audit-Logs mit einem Key aus einem KMIP-Server. Nur autorisierte Personen mit Zugriff zum KMS können die Logs entschlüsseln. Dies erfüllt regulatorische Anforderungen und schützt sensible Audit-Daten.

Die folgende Tabelle fasst die Hauptneuerungen zusammen:

Feature Kategorie Hauptvorteil Typischer Use Case
$densify Aggregation Lückenlose Zeitreihen IoT-Daten mit Ausfällen
$fill Aggregation Fehlende Werte ergänzen Unvollständige Sensor-Logs
$topN / $bottomN Aggregation Effiziente Rankings Sales-Leaderboards
$firstN / $lastN Aggregation Sequenz-Extraktion Letzte N Transaktionen
$linearFill / $locf Aggregation Wert-Interpolation Finanz-Zeitreihen
$sortArray Aggregation Array-Manipulation Review-Sortierung
$documents Aggregation Inline-Daten Tests, Referenz-Joins
$shardedDataDistribution Sharding Verteilungs-Transparenz Cluster-Monitoring
Change Streams Optimierung Performance 30-50% weniger RAM Microservice-Architekturen
Cluster Parameter Operations Zentrale Konfiguration Multi-Node-Deployments
128 MB Chunks Sharding Weniger Chunk-Overhead Multi-Terabyte-Clusters
Audit-Log-Verschlüsselung Security Compliance Healthcare, Finanz

MongoDB 6.0 war eine konsequente Weiterentwicklung der Analytics-Fähigkeiten, die mit Time Series Collections in 5.0 begonnen hatten. Die neuen Aggregations-Operatoren adressierten reale Probleme bei der Arbeit mit unvollständigen oder lückenhaften Daten – Probleme, die jeder kennt, der mit Zeitreihendaten gearbeitet hat. Die operativen Verbesserungen für Change Streams und Clusterkonfiguration zeigten, dass MongoDB auch an der Skalierung und Verwaltbarkeit großer Deployments arbeitete. Für bestehende Nutzer brachte 6.0 inkrementelle aber spürbare Verbesserungen. Für neue Analytics-Workloads machte es MongoDB zu einer stärkeren Alternative zu spezialisierten Zeitreihen-Datenbanken.