#!/bin/bash
# mongo_ui.sh - MongoDB Terminal Explorer
# ----------------------------------------
# View MongoDBs locally from a Linux shell window in an easy-to-use terminal UI.
# Only tested in Ubuntu, because that's all I have.
#
# This script connects to a MongoDB instance and allows you to:
# - Select a database and collection using fzf
# - View a sample document
# - View inferred schema types
# - View the top 10 documents in a collection
#
# 🔒 This tool is strictly read-only. It does not write, update, or delete any data.
#
# ✅ Requirements:
# - fzf: sudo apt install fzf
# - jq: sudo apt install jq
# - mongosh: https://www.mongodb.com/try/download/shell
#
# 🪪 License: MIT
# You are free to use, modify, and share this script however you'd like.
# There is absolutely NO WARRANTY — use at your own risk.
# War is bad. Cookies are good! Except the tracking kind.
MONGO_URI="mongodb://localhost:27017"
# Check deps
command -v fzf >/dev/null || { echo "fzf not found. Try: sudo apt install fzf"; exit 1; }
command -v jq >/dev/null || { echo "jq not found. Try: sudo apt install jq"; exit 1; }
command -v mongosh >/dev/null || { echo "mongosh not found. See: https://www.mongodb.com/try/download/shell"; exit 1; }
# Graceful shutdown on Ctrl-C, Ctrl-\, or kill
trap "echo -e '\n[INFO] Exiting...'; exit 0" SIGINT SIGQUIT SIGTERM
# Fetch and display database list. Either run this code
read -n 1 -s -r -p "Press any key to fetch databases..."; echo
RAW_DBS=$(mongosh "$MONGO_URI" --quiet --eval "JSON.stringify(db.adminCommand('listDatabases'))")
DB=$(echo "$RAW_DBS" | jq -r '.databases[].name' | fzf --prompt="Select Database: ")
[ -z "$DB" ] && exit
# -- OR --
#DB="<HARDCODE YOUR DB HERE>"
echo "You selected: $DB"
while true; do
read -n 1 -s -r -p "Press any key to fetch collections from $DB..."; echo
RAW_COLLS=$(mongosh "$MONGO_URI/$DB" --quiet --eval "JSON.stringify(db.getCollectionNames())")
COLLECTION=$(echo "$RAW_COLLS" | jq -r '.[]' | fzf --prompt="Select Collection (or ESC to quit): ")
[ -z "$COLLECTION" ] && exit
echo "You selected collection: $COLLECTION"
while true; do
ACTION=$(printf "View Sample Document\nView Schema (Quick)\nView Top 10 Rows\nBack\nExit" | fzf --prompt="Choose Action: ")
[ "$ACTION" == "Back" ] && break
[ "$ACTION" == "Exit" ] && exit
if [ "$ACTION" == "View Sample Document" ]; then
read -n 1 -s -r -p "Press any key to fetch a sample document..."; echo
RAW_DOC=$(mongosh "$MONGO_URI/$DB" --quiet --eval "JSON.stringify(db.getCollection('$COLLECTION').findOne())")
echo "$RAW_DOC" | jq .
echo
read -n 1 -s -r -p "Done. Press any key to return to the previous menu..."
elif [ "$ACTION" == "View Schema (Quick)" ]; then
echo "[INFO] Sampling data..."
RAW=$(mongosh --quiet --eval "JSON.stringify(db.getCollection('$COLLECTION').find().limit(100).toArray())" "$MONGO_URI/$DB")
if [[ -z "$RAW" || "$RAW" == "undefined" || "$RAW" == "[]" ]]; then
echo "[WARN] No documents found or error fetching data."
else
echo "$RAW" | jq '
map(to_entries)
| flatten
| group_by(.key)
| map({ key: .[0].key, types: (map(.value | type) | unique | join("/")) })
| map({ (.key): .types })
| add
'
fi
echo
read -n 1 -s -r -p "Done. Press any key to return to the previous menu..."
elif [ "$ACTION" == "View Top 10 Rows" ]; then
RAW_TOP=$(mongosh "$MONGO_URI/$DB" --quiet --eval "JSON.stringify(db.getCollection('$COLLECTION').find().limit(10).toArray())")
echo "$RAW_TOP" | jq -c '.[]' | while read -r doc; do echo "$doc" | jq .; echo; done
echo
read -n 1 -s -r -p "Done. Press any key to return to the previous menu..."
fi
done
done