Die MongoDB Shell – mongosh – ist mehr als ein simples Command-Line-Interface. Sie ist eine vollwertige JavaScript-Umgebung, ein Debugging-Tool, ein Prototyping-Environment und oft der erste Kontaktpunkt zwischen Entwicklern und MongoDB. Wer mongosh beherrscht, kann Daten explorieren, Queries testen, Maintenance-Tasks durchführen und komplexe Aggregations-Pipelines entwickeln – alles ohne eine Zeile Anwendungs-Code zu schreiben.
mongosh ersetzte 2020 die alte mongo-Shell und brachte
fundamentale Verbesserungen: Syntax-Highlighting, Autocomplete, moderne
JavaScript-Support (ES2020+), bessere Error-Messages und eine extendible
Plugin-Architektur. Für Entwickler, die aus modernen
JavaScript-Umgebungen kommen, fühlt sich mongosh vertraut an. Für Admins
ist sie ein mächtiges Tool für ad-hoc-Queries und schnelles
Troubleshooting. Die Lernkurve ist flach, aber die Tiefe ist
erheblich.
Das Starten von mongosh ohne Parameter verbindet zu localhost:27017 – dem MongoDB-Default:
mongoshDie Shell zeigt eine Willkommens-Message mit Version-Info, Verbindungs-Details und einem Prompt:
Current Mongosh Log ID: 65abc123def456789012345
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true
Using MongoDB: 7.0.5
Using Mongosh: 2.1.1
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
test>
Der Prompt zeigt die aktuelle Datenbank – “test” ist der Default. Man
ist sofort interaktiv und kann Befehle eingeben. Das
test>-Prefix ändert sich, wenn man Datenbanken wechselt,
was Orientierung gibt.
Für Verbindungen zu Remote-Hosts oder mit Authentifizierung nutzt man Connection Strings:
# Remote Host mit Port
mongosh "mongodb://server.example.com:27017"
# Mit Authentifizierung
mongosh "mongodb://admin:password@server.example.com:27017/admin"
# Replica Set
mongosh "mongodb://server1,server2,server3/mydb?replicaSet=myrs"
# Mit TLS/SSL
mongosh "mongodb://server.example.com:27017/?tls=true&tlsCAFile=/path/to/ca.pem"Connection Strings folgen dem MongoDB URI-Format. Alle Optionen – Authentifizierung, Replica Set, Read Preference, TLS – können im String kodiert werden. Für komplexe Setups ist dies übersichtlicher als multiple CLI-Flags.
Nach erfolgreicher Verbindung hat man Zugriff auf das
db-Objekt – das zentrale Interface zu MongoDB.
db referenziert die aktuelle Datenbank. Methoden auf
db führen Datenbankoperationen aus, Methoden auf
db.<collection> operieren auf Collections.
Wer mit einem neuen MongoDB-System arbeitet, startet typischerweise mit Exploration. Welche Datenbanken existieren? Welche Collections? Wie sehen die Dokumente aus?
// Alle Datenbanken listen
show dbs
// Oder expliziter
db.adminCommand({ listDatabases: 1 })
// Zu einer Datenbank wechseln
use myapp
// Collections in aktueller Datenbank
show collections
// Oder
db.getCollectionNames()Das use-Command wechselt die aktuelle Datenbank.
Existiert die Datenbank nicht, erstellt MongoDB sie beim ersten Write
implizit. Dies ist schemaless-Convenience – keine expliziten CREATE
DATABASE-Statements nötig.
Um zu sehen, wie Dokumente strukturiert sind, fetcht man ein paar Samples:
// Ein Dokument
db.users.findOne()
// Fünf Dokumente
db.users.find().limit(5)
// Mit Pretty-Print für bessere Lesbarkeit
db.users.find().limit(5).pretty()Die .pretty()-Methode formatiert JSON mit Indentation.
Moderne mongosh-Versionen pretty-printen automatisch, aber explizites
.pretty() funktioniert noch für Kompatibilität.
Um zu verstehen, wie Felder verteilt sind oder welche Typen existieren, hilft Aggregation:
// Eindeutige Werte eines Feldes
db.users.distinct("status")
// Zählung nach Typ eines Feldes
db.users.aggregate([
{ $group: {
_id: { $type: "$age" },
count: { $sum: 1 }
}}
])Diese explorierenden Queries sind essentiell beim Debugging oder wenn man mit unfamiliären Daten arbeitet. Ein paar Minuten Exploration spart Stunden frustrierender “warum funktioniert meine Query nicht?”-Debugging.
mongosh ist keine Domain-Specific Language, sondern eine vollwertige JavaScript-Umgebung. Man kann Variablen definieren, Funktionen schreiben, Control-Flow nutzen – beliebigen JavaScript-Code:
// Variablen und Konstanten
const dbName = "production"
let userCount = 0
// Funktionen
function countActiveUsers() {
return db.users.countDocuments({ status: "active" })
}
// Loops
for (let i = 0; i < 10; i++) {
db.testdata.insertOne({
num: i,
squared: i * i,
timestamp: new Date()
})
}
// Conditionals
const count = db.users.countDocuments()
if (count > 1000000) {
print("Database is large, consider archiving")
} else {
print("Database size is manageable")
}Diese Programmierbarkeit ist mächtig für komplexe Tasks. Ein Beispiel: Bulk-Update mit komplexer Logik:
// Iteriere über alle inactive Users und archiviere sie
db.users.find({ status: "inactive", lastLogin: { $lt: new Date("2023-01-01") } })
.forEach(user => {
// Archiviere in separate Collection
db.archivedUsers.insertOne({
...user,
archivedAt: new Date(),
archivedReason: "Inactive for over 1 year"
})
// Lösche Original
db.users.deleteOne({ _id: user._id })
// Log
print(`Archived user ${user.username}`)
})Dieser Code macht etwas, das in einer single-Query schwierig wäre:
Multi-step-Operation mit Logging. Die .forEach()-Methode
auf Cursors ist essentiell für solche Tasks.
mongosh unterstützt moderne JavaScript-Features wie async/await. Viele MongoDB-Operationen sind asynchron, und async/await macht den Code lesbarer als Callback-Hell:
// Async Funktion
async function getUserWithOrders(userId) {
const user = await db.users.findOne({ _id: userId })
if (!user) {
throw new Error("User not found")
}
const orders = await db.orders.find({ customerId: userId }).toArray()
return {
...user,
orderCount: orders.length,
totalSpent: orders.reduce((sum, o) => sum + o.total, 0)
}
}
// Ausführen
getUserWithOrders(ObjectId("..."))
.then(result => printjson(result))
.catch(err => print("Error:", err))
// Oder mit await im Top-Level (ES2022+)
const result = await getUserWithOrders(ObjectId("..."))
printjson(result)Top-Level await ist in mongosh verfügbar – keine Wrapper-Function nötig. Dies ist praktisch für schnelle Scripts.
Eine der größten Verbesserungen von mongosh über die alte
mongo-Shell ist Autocomplete. Drückt man Tab, zeigt mongosh
verfügbare Methoden:
db.users.find<TAB>
// Zeigt: find, findAndModify, findOne, findOneAndDelete, findOneAndReplace, findOneAndUpdate
db.users.find().<TAB>
// Zeigt Cursor-Methoden: limit, skip, sort, count, explain, forEach, map, ...Dies ist nicht nur Convenience, sondern Discovery-Tool. Man muss nicht die Dokumentation öffnen, um zu sehen, welche Methoden existieren. Das Autocomplete ist context-aware – es weiß, ob man auf einem Collection-Objekt, einem Cursor oder der Datenbank ist.
Die .help()-Methoden geben detailliertere Info:
// Hilfe für Datenbank-Operationen
db.help()
// Hilfe für Collection-Operationen
db.users.help()
// Hilfe für spezifische Methode
db.users.find.help()Die Help-Messages sind konzise aber informativ, oft mit Beispiel-Syntax.
Für längeren Code ist die interaktive Zeile-für-Zeile-Eingabe
umständlich. Der .editor-Command öffnet einen Editor im
Terminal:
.editor
// Editor öffnet sichIm Editor kann man mehrzeiligen Code schreiben, mit Syntax-Highlighting und ohne dass jede Zeile sofort executed wird. Nach Beenden (typischerweise Ctrl+D oder Ctrl+Z je nach System) wird der gesamte Code als Block ausgeführt.
Dies ist ideal für komplexe Aggregations-Pipelines oder Scripts mit
mehreren Funktionen. Die Alternative wäre, Code in eine
.js-Datei zu schreiben und mit load() zu
importieren:
// code.js enthält Funktionen und Scripts
load("./myScripts.js")
// Funktionen aus der Datei sind nun verfügbar
myCustomFunction()Die load()-Funktion ist nützlich für wiederverwendbare
Scripts oder wenn man Code versionskontrollieren will.
mongosh 2.0+ hat ein Snippet-System – die Möglichkeit, häufig genutzte Code-Blöcke zu speichern und mit Namen abzurufen:
// Snippet speichern
snippet.save("activeUsers", `
db.users.find({
status: "active",
lastLogin: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }
}).count()
`, "Count active users from last 30 days")
// Snippet ausführen
snippet.run("activeUsers")
// Alle Snippets listen
snippet.list()
// Snippet löschen
snippet.delete("activeUsers")Snippets werden persistent gespeichert (in
~/.mongodb/mongosh/snippets) und sind über Sessions hinweg
verfügbar. Für oft wiederholte Queries oder Maintenance-Tasks ist dies
ein Time-Saver.
Eine der mächtigsten Debugging-Tools in mongosh ist
.explain(). Es zeigt, wie MongoDB eine Query ausführt –
welche Indizes genutzt werden, wie viele Dokumente gescannt wurden, wie
lange es dauerte:
// Explain für find
db.users.find({ age: { $gt: 25 } }).explain("executionStats")
// Explain für Aggregation
db.orders.aggregate([
{ $match: { status: "shipped" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } }
]).explain("executionStats")Das "executionStats"-Level gibt detaillierte
Performance-Daten. Die Output ist umfangreich, aber die wichtigsten
Felder:
executionTimeMillis: Wie lange dauerte die Query?totalDocsExamined: Wie viele Dokumente wurden
gescannt?totalKeysExamined: Wie viele Index-Einträge wurden
gescannt?executionStages.stage: Welche Strategie wurde genutzt
(COLLSCAN, IXSCAN, etc.)?Eine Query mit COLLSCAN (Collection Scan) und
totalDocsExamined gleich Millionen ist ein Red Flag – sie
scannt die gesamte Collection. Ein fehlender Index ist wahrscheinlich.
Die ideale Query hat totalKeysExamined ähnlich oder kleiner
als returned Documents und nutzt IXSCAN.
mongosh ist nicht nur für Queries, sondern auch für Administration. Viele admin-Tasks, die sonst GUIs oder separate Tools erfordern, sind in der Shell möglich.
Benutzer erstellen:
use admin
db.createUser({
user: "appUser",
pwd: "securePassword123",
roles: [
{ role: "readWrite", db: "myapp" },
{ role: "read", db: "analytics" }
]
})Indizes verwalten:
// Index erstellen
db.users.createIndex({ email: 1 }, { unique: true })
// Alle Indizes einer Collection
db.users.getIndexes()
// Index löschen
db.users.dropIndex("email_1")Replica Set Status:
rs.status()
rs.conf()Sharded Cluster Info:
sh.status()Database Stats:
db.stats()
db.users.stats()Diese Commands geben JSON-Output, den man programmatisch weiterverarbeiten kann. Für automatisierte Monitoring-Scripts oder Custom-Admin-Tools ist mongosh oft der einfachste Weg.
MongoDB hat einen Profiler, der langsame Queries logged. Man kann ihn in mongosh aktivieren und analysieren:
// Profiler aktivieren (Level 2: log alle Operationen)
db.setProfilingLevel(2)
// Oder nur Slow Queries (>100ms)
db.setProfilingLevel(1, { slowms: 100 })
// Profiler-Daten analysieren
db.system.profile.find().sort({ ts: -1 }).limit(10)
// Slowest Queries finden
db.system.profile.find({ millis: { $gt: 1000 } }).sort({ millis: -1 })Die system.profile-Collection speichert alle geloggten
Operations. Jedes Dokument enthält Query-Details, Execution-Time,
genutzten Index, etc. Für Performance-Debugging ist dies Gold.
mongosh kann Scripts von Dateien ausführen, was Automation ermöglicht:
# Script ausführen
mongosh --file script.js
# Mit Connection String
mongosh "mongodb://server:27017/mydb" --file migration.js
# Quiet Mode (nur Output, kein Prompt/Banner)
mongosh --quiet --file cleanup.jsEin typisches Migrations-Script könnte so aussehen:
// migration.js
print("Starting migration...")
const result = db.users.updateMany(
{ country: { $exists: false } },
{ $set: { country: "UNKNOWN" } }
)
print(`Updated ${result.modifiedCount} documents`)
// Validation
const missingCountry = db.users.countDocuments({ country: { $exists: false } })
if (missingCountry > 0) {
print(`ERROR: ${missingCountry} documents still missing country field`)
quit(1) // Exit mit Error-Code
}
print("Migration completed successfully")Dieses Script updated Dokumente, validiert das Resultat und exitiert mit Error-Code bei Problemen. In CI/CD-Pipelines kann man den Exit-Code prüfen, um Success/Failure zu detektieren.
Command History: mongosh speichert History in
~/.mongodb/mongosh/.mongosh_repl_history. Man kann mit
Pfeiltasten durch vorherige Commands navigieren. Ctrl+R startet
Reverse-Search durch History.
Output-Formatting: Für große Outputs ist
.pretty() hilfreich, aber für maschinelle Verarbeitung ist
kompaktes JSON besser. Die printjson()-Funktion gibt
formatiertes JSON aus:
const result = db.users.findOne()
printjson(result)Exit: Um mongosh zu beenden: exit,
quit() oder Ctrl+D.
Clear Screen: cls oder Ctrl+L löscht
den Bildschirm.
Telemetrie: mongosh sammelt anonyme Usage-Statistiken (welche Commands genutzt werden, Crash-Reports). Dies ist opt-out:
disableTelemetry()Config File: mongosh kann eine Config-Datei nutzen
für persistente Settings. Die Datei ist ~/.mongoshrc.js und
wird beim Start automatisch executed:
// ~/.mongoshrc.js
// Automatisch executed bei jedem mongosh-Start
// Helper-Funktionen definieren
function countAll(collectionName) {
return db[collectionName].countDocuments()
}
// Default-Einstellungen
DBQuery.shellBatchSize = 10 // Nur 10 Dokumente per Batch statt 20
print("Custom mongoshrc loaded! Use countAll('collectionName') for quick counts")Die .mongoshrc.js ist wie .bashrc für Bash
– ein Platz für persönliche Customizations und Helper-Functions.
Die folgende Tabelle fasst wichtige mongosh-Features zusammen:
| Feature | Zweck | Typischer Use-Case |
|---|---|---|
| Autocomplete (Tab) | Discovery | Methoden explorieren |
.explain() |
Performance-Analyse | Slow Queries debuggen |
.editor |
Multi-Line-Code | Komplexe Scripts schreiben |
snippet |
Code-Reuse | Häufige Queries speichern |
load() |
Script-Import | Wiederverwendbare Functions |
.help() |
Dokumentation | Quick Reference |
db.stats() |
Monitoring | Speicher-Nutzung prüfen |
rs.status() |
Replica Set Admin | Replication checken |
.mongoshrc.js |
Customization | Persönliche Helpers |
mongosh ist mehr als ein Terminal-Interface zu MongoDB. Es ist ein vollwertiges Development-Environment, ein Admin-Tool und oft der schnellste Weg, um Daten zu explorieren, Queries zu testen oder Maintenance-Tasks durchzuführen. Die moderne JavaScript-Integration macht es vertraut für Web-Entwickler. Die mächtigen Features wie Explain, Profiling und Snippets machen es essentiell für Performance-Tuning und Troubleshooting. Wer mongosh meistert, hat ein Werkzeug, das in nahezu jedem MongoDB-Workflow nützlich ist – von ersten Prototypen bis zu komplexen Produktions-Deployments.