MongoDB stores data as documents — JSON-like objects with flexible structure. No fixed schema. No joins required for embedded data. This tutorial gets you up and running with MongoDB 8.0.
Setup with Docker
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongodb/mongodb-community-server:8.0-ubi8
Connect with mongosh:
mongosh "mongodb://admin:password@localhost:27017"
mongosh Basics
// Show databases
show dbs
// Switch to (or create) a database
use myapp
// Show collections
show collections
// Create a collection explicitly (optional — auto-created on first insert)
db.createCollection("users")
Documents and Collections
In MongoDB:
- A document is a JSON-like record (similar to a row in SQL)
- A collection is a group of documents (similar to a table)
- Every document has an
_idfield — auto-generated as anObjectIdif not provided
// A MongoDB document
{
_id: ObjectId("64f1a2b3c4d5e6f7a8b9c0d1"),
name: "Alex Johnson",
email: "alex@example.com",
age: 28,
address: {
city: "Berlin",
country: "Germany"
},
tags: ["developer", "nodejs"],
createdAt: ISODate("2026-01-15T10:00:00Z")
}
Insert
// Insert one document
db.users.insertOne({
name: "Alex Johnson",
email: "alex@example.com",
age: 28
})
// Insert multiple documents
db.users.insertMany([
{ name: "Sam Lee", email: "sam@example.com", age: 32 },
{ name: "Jordan Kim", email: "jordan@example.com", age: 25 }
])
Find (Read)
// Find all documents
db.users.find()
// Find with filter
db.users.find({ age: { $gt: 25 } })
// Find one
db.users.findOne({ email: "alex@example.com" })
// Projection — include/exclude fields (1 = include, 0 = exclude)
db.users.find({}, { name: 1, email: 1, _id: 0 })
// Sort, limit, skip
db.users.find().sort({ age: -1 }).limit(10).skip(20)
Common query operators:
| Operator | Meaning | Example |
|---|---|---|
$eq | Equals | { age: { $eq: 28 } } |
$ne | Not equals | { status: { $ne: "deleted" } } |
$gt / $gte | Greater than | { age: { $gte: 18 } } |
$lt / $lte | Less than | { price: { $lt: 100 } } |
$in | In array | { status: { $in: ["active", "pending"] } } |
$regex | Regex match | { name: { $regex: /^Alex/i } } |
$exists | Field exists | { phone: { $exists: true } } |
Update
// Update one document
db.users.updateOne(
{ email: "alex@example.com" },
{ $set: { age: 29, updatedAt: new Date() } }
)
// Update many
db.users.updateMany(
{ age: { $lt: 18 } },
{ $set: { isMinor: true } }
)
// Upsert — insert if not found
db.users.updateOne(
{ email: "new@example.com" },
{ $set: { name: "New User", age: 20 } },
{ upsert: true }
)
Common update operators:
| Operator | What it does |
|---|---|
$set | Set field value |
$unset | Remove a field |
$inc | Increment a number |
$push | Add item to array |
$pull | Remove item from array |
$addToSet | Add to array if not already present |
Delete
// Delete one
db.users.deleteOne({ email: "alex@example.com" })
// Delete many
db.users.deleteMany({ createdAt: { $lt: ISODate("2020-01-01") } })
Node.js with Mongoose 8
Mongoose adds schema validation and a cleaner API on top of the MongoDB Node.js driver.
npm install mongoose
import mongoose, { Schema, Document } from "mongoose";
// Connect
await mongoose.connect("mongodb://admin:password@localhost:27017/myapp?authSource=admin");
// Define schema
const userSchema = new Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true, lowercase: true },
age: { type: Number, min: 0 },
tags: [String],
createdAt: { type: Date, default: Date.now },
});
const User = mongoose.model("User", userSchema);
// Create
const user = await User.create({
name: "Alex Johnson",
email: "alex@example.com",
age: 28,
});
// Find
const users = await User.find({ age: { $gte: 18 } })
.sort({ createdAt: -1 })
.limit(10);
// Update
await User.findByIdAndUpdate(user._id, { age: 29 }, { new: true });
// Delete
await User.findByIdAndDelete(user._id);
Python with PyMongo
pip install pymongo
from pymongo import MongoClient
from datetime import datetime, timezone
client = MongoClient("mongodb://admin:password@localhost:27017/")
db = client["myapp"]
users = db["users"]
# Insert
result = users.insert_one({
"name": "Alex Johnson",
"email": "alex@example.com",
"age": 28,
"created_at": datetime.now(timezone.utc)
})
print(f"Inserted: {result.inserted_id}")
# Find
for user in users.find({"age": {"$gte": 18}}).sort("age", -1).limit(5):
print(user["name"], user["age"])
# Update
users.update_one(
{"email": "alex@example.com"},
{"$set": {"age": 29}}
)
# Delete
users.delete_one({"email": "alex@example.com"})
client.close()
What’s Next?
You can now read and write data in MongoDB. Next: data modeling — the key skill that separates fast MongoDB apps from slow ones.
Next: Database Tutorial #10: MongoDB Data Modeling