#!/usr/bin/env bash set -euo pipefail usage() { echo "Usage: $0 --uri --db --input [--dry-run]" echo "" echo " --uri MongoDB connection URI (e.g. mongodb://user:pass@host:27017/admin)" echo " --db Database name" echo " --input Path to input JSON file" echo " --dry-run Show planned actions without executing them" exit 1 } URI="" DB="" INPUT="" DRY_RUN="false" while [[ $# -gt 0 ]]; do case "$1" in --uri) URI="$2"; shift 2 ;; --db) DB="$2"; shift 2 ;; --input) INPUT="$2"; shift 2 ;; --dry-run) DRY_RUN="true"; shift ;; *) echo "Unknown argument: $1"; usage ;; esac done [[ -z "$URI" ]] && echo "Error: --uri is required" && usage [[ -z "$DB" ]] && echo "Error: --db is required" && usage [[ -z "$INPUT" ]] && echo "Error: --input is required" && usage [[ ! -f "$INPUT" ]] && echo "Error: input file not found: $INPUT" && exit 1 TMP_JS=$(mktemp /tmp/mongo-import-XXXXXX.js) trap 'rm -f "$TMP_JS"' EXIT cat > "$TMP_JS" <<'EOF' const dbName = process.env.MONGO_DB; const dryRun = process.env.DRY_RUN === "true"; const data = JSON.parse(process.env.INDEXES_JSON); const targetDb = db.getSiblingDB(dbName); const existingCollections = new Set(targetDb.getCollectionNames()); if (dryRun) { print("[dry-run] No changes will be made.\n"); } for (const [collName, indexes] of Object.entries(data)) { if (!existingCollections.has(collName)) { if (dryRun) { print(`[dry-run] Would create collection: ${collName}`); } else { targetDb.createCollection(collName); print(`Created collection: ${collName}`); } } const existingIndexes = targetDb.getCollection(collName).getIndexes() .filter(idx => idx.name !== "_id_"); if (existingIndexes.length > 0) { if (dryRun) { const names = existingIndexes.map(i => i.name).join(", "); print(`[dry-run] Would drop indexes on ${collName}: ${names}`); } else { targetDb.getCollection(collName).dropIndexes(); print(`Dropped existing indexes on: ${collName}`); } } for (const idx of indexes) { if (idx.name === "_id_") continue; const { key, name, ...rest } = idx; const options = { name, ...rest }; if (dryRun) { print(`[dry-run] Would create index on ${collName}: ${JSON.stringify({ key, options })}`); } else { targetDb.getCollection(collName).createIndex(key, options); print(`Created index "${name}" on: ${collName}`); } } } if (!dryRun) { print("\nImport complete."); } EOF MONGO_DB="$DB" \ DRY_RUN="$DRY_RUN" \ INDEXES_JSON="$(cat "$INPUT")" \ mongosh --quiet "$URI" --file "$TMP_JS"