Setting up MongoDB: Atlas, local install and mongosh
Choose between a local server, a container and Atlas, connect with mongosh, and get data in and out with CRUD, bulk writes and the import tools.
Local install, container or Atlas
| Option | Good for | What you take on |
|---|---|---|
Local mongod | Development and offline work | You own backups, upgrades and disk |
| Docker with a volume | Throwaway and reproducible environments | Data lives in the volume, not the container |
| Atlas free or shared tier | Prototypes and small projects | Connection limits and shared performance |
| Atlas dedicated cluster | Production | Cost, and a different feature set per tier |
# macOS
brew tap mongodb/brew
brew install [email protected]
brew services start [email protected]
# Docker with a persistent volume
docker run -d --name mongo -p 27017:27017 \
-v mongo-data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=secret \
mongo:8.0
# the shell
mongosh "mongodb://root:secret@localhost:27017/?authSource=admin"
mongosh "mongodb+srv://user:[email protected]/shop"mongoshis the current shell and replaces the legacymongobinary; the old shell does not support newer server features.- The connection string decides everything.
authSourcenames the database the credentials live in, andmongodb+srvdiscovers the replica set members from DNS. - On Atlas, an IP access list entry is required before any connection succeeds. A timeout rather than an authentication error usually means the address is not allowlisted.
- A replica set is not optional in practice: transactions and change streams both require one, and Atlas provides it by default.
CRUD from mongosh
use shop
db.orders.insertOne({
customer: "Ada",
total: NumberDecimal("19.90"),
status: "new",
placedAt: new Date()
})
db.orders.insertMany([
{ customer: "Grace", total: NumberDecimal("5.00"), status: "new" },
{ customer: "Linus", total: NumberDecimal("7.25"), status: "new" }
], { ordered: false }) // keep going after a failed document
db.orders.find({ status: "new" }).sort({ total: -1 }).limit(5)
db.orders.updateMany({ status: "new" }, { $set: { status: "queued" } })
db.orders.deleteMany({ status: "cancelled" })
db.orders.countDocuments({ total: { $gt: 10 } })use shopswitches the current database and creates it lazily on the first write.ordered: falsemakes a bulk insert continue after a failure, and the returned error report lists exactly which documents were rejected.NumberDecimalandnew Date()build BSON values, not JavaScript ones. Storing a date as a string is the single most common way to break range queries later.- A
findreturns a cursor, not an array. In the shell a cursor is printed for you, but in code you must iterate it or call a terminal method.
Bulk writes and importing data
mongoimport --uri "mongodb://localhost:27017/shop" \
--collection customers --file customers.json --jsonArray
mongoexport --uri "mongodb://localhost:27017/shop" \
--collection orders --out orders.json
# run a script that seeds a development database
mongosh "mongodb://localhost:27017/shop" --file seed.js
# check without opening the shell
mongosh "mongodb://localhost:27017/shop" --eval 'db.orders.countDocuments()'💡
Make every import idempotent: upsert on a natural key instead of inserting blindly, so re-running the same file repairs the state rather than duplicating it. Half-loaded collections are far more common than genuinely corrupted ones.
FAQ
Should I start on Atlas or locally?
Start locally if you want to learn the shell and the data model with no network in the way. Start on Atlas if you want a replica set from minute one, because transactions and change streams need one and you will otherwise hit that wall later.
Why does my connection time out instead of failing authentication?
A timeout is a network or firewall problem: an address missing from the Atlas access list, a container that cannot reach the host, or a DNS issue with an SRV record. A credential problem returns an authentication error quickly.
Related
Documents, collections and queries Backup, restore and operational tooling
Last refreshed 2026-09-18.