MongoDB Get Started
Learn how to install MongoDB, connect with PyMongo, and perform basic CRUD operations in Python with clear, working examples.
This chapter introduces MongoDB and shows you how to use it from Python using the PyMongo driver. By the end you will have MongoDB installed, a working connection, and a clear picture of how to insert, query, update, and delete documents.
What is MongoDB?
MongoDB is a document database — a type of NoSQL database that stores records as JSON-like documents instead of rows and columns. Each document is a self-contained object that can have nested fields and arrays, which makes it a natural fit for data that does not fit neatly into a fixed schema.
Key characteristics:
- Schema-flexible. Two documents in the same collection can have completely different fields.
- Rich query language. Filter, project, sort, limit, and aggregate with a single driver call.
- Horizontal scalability. Built-in sharding and replica sets handle large data volumes and high availability.
- JSON-native. Documents are stored as BSON (Binary JSON), so Python dicts map directly to MongoDB documents.
When to choose MongoDB over a relational database
| Situation | Good fit? |
|---|---|
| Rapidly changing data shape (prototypes, APIs) | Yes |
| Hierarchical / nested data | Yes |
Complex multi-table JOIN queries | Prefer SQL |
Strong ACID transactions across many tables | Prefer SQL |
| Full-text search at scale | Combine with Elasticsearch |
Installing MongoDB
Option 1 — Local installation
Download the MongoDB Community Server from mongodb.com/try/download/community, choose your OS, and follow the installer. Then start the server:
# macOS / Linux
mongod --dbpath /data/db
# Windows (PowerShell, run as Administrator)
mongod --dbpath "C:\data\db"Verify MongoDB is running by opening a second terminal and running:
mongosh --eval "db.adminCommand('ping')"Expected output:
{ ok: 1 }Option 2 — Docker (quickest for development)
If you have Docker installed, you can skip local installation entirely:
docker run -d --name mongo -p 27017:27017 mongo:7This pulls the official MongoDB 7 image and exposes port 27017 on your machine. Stop it with docker stop mongo.
Option 3 — MongoDB Atlas (cloud)
Atlas is MongoDB's fully-managed cloud service with a free tier. After signing up, copy the connection string from the dashboard — it looks like:
mongodb+srv://username:[email protected]/You can use that URI anywhere you see mongodb://localhost:27017/ in this chapter.
Installing the PyMongo Driver
PyMongo is the official Python driver for MongoDB. Install it with pip:
pip install pymongoTo use MongoDB Atlas, also install the extras that include the DNS resolver:
pip install "pymongo[srv]"Verify the installation:
import pymongo
print(pymongo.version)
# e.g. 4.7.3Connecting to MongoDB
MongoClient is the entry point for all driver operations. Create one client per application and reuse it — the client manages an internal connection pool.
from pymongo import MongoClient
# Local server with default host and port
client = MongoClient("mongodb://localhost:27017/")
# Verify connectivity (raises ConnectionFailure if the server is unreachable)
client.admin.command("ping")
print("Connected successfully")For production code, always handle connection errors explicitly:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient("mongodb://localhost:27017/", serverSelectionTimeoutMS=3000)
try:
client.admin.command("ping")
print("Connected to MongoDB")
except ConnectionFailure as e:
print("Connection failed:", e)Connection string format
mongodb://[username:password@]host[:port][/database][?options]Common options:
| Option | Example | Purpose |
|---|---|---|
authSource | authSource=admin | Database used for authentication |
replicaSet | replicaSet=rs0 | Connect to a replica set |
tls=true | tls=true | Enable TLS/SSL |
serverSelectionTimeoutMS | serverSelectionTimeoutMS=5000 | Timeout for server selection |
Databases and Collections
MongoDB organises data in a two-level hierarchy:
- A database groups related collections (similar to an SQL schema or database).
- A collection holds documents (similar to an SQL table, but schema-free).
Both are created lazily — they come into existence the first time you insert a document. You never run CREATE DATABASE or CREATE TABLE.
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
# Reference a database (not yet created on disk)
db = client["mystore"]
# Reference a collection inside it (also not yet on disk)
products = db["products"]
# The database and collection are created when the first document is insertedBasic CRUD Operations
The following examples build on each other. Run them in order if you are following along interactively.
Create — insert documents
Use insert_one() for a single document and insert_many() for a batch:
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
db = client["mystore"]
products = db["products"]
# Insert a single document
result = products.insert_one({
"name": "Laptop",
"brand": "Acme",
"price": 999.99,
"in_stock": True
})
print("Inserted id:", result.inserted_id)
# Insert multiple documents at once
new_products = [
{"name": "Mouse", "brand": "Acme", "price": 29.99, "in_stock": True},
{"name": "Keyboard", "brand": "Acme", "price": 79.99, "in_stock": False},
{"name": "Monitor", "brand": "Zeta", "price": 349.99, "in_stock": True},
]
batch_result = products.insert_many(new_products)
print("Inserted ids:", batch_result.inserted_ids)MongoDB automatically adds an _id field (of type ObjectId) to every document if you do not supply one. This field is the primary key and is always unique within a collection.
Read — query documents
find_one() returns the first matching document (or None). find() returns a cursor you can iterate over.
# Retrieve one document (no filter = the first document in natural order)
doc = products.find_one()
print(doc)
# Retrieve all documents in the collection
for p in products.find():
print(p["name"], "-", p["price"])
# Filter: products that are in stock
for p in products.find({"in_stock": True}):
print(p["name"])
# Projection: return only name and price (exclude _id)
for p in products.find({}, {"_id": 0, "name": 1, "price": 1}):
print(p)Query operators
MongoDB's query language uses operators prefixed with $:
# Products cheaper than £100
cheap = products.find({"price": {"$lt": 100}})
# In-stock products from brand "Acme" or "Zeta"
multi = products.find({
"in_stock": True,
"brand": {"$in": ["Acme", "Zeta"]}
})
# Price between 50 and 500 (inclusive)
range_q = products.find({"price": {"$gte": 50, "$lte": 500}})Common comparison operators:
| Operator | Meaning |
|---|---|
$eq | Equal (default when using {"field": value}) |
$ne | Not equal |
$gt / $gte | Greater than / greater than or equal |
$lt / $lte | Less than / less than or equal |
$in | Value is in a list |
$nin | Value is not in a list |
Update — modify documents
update_one() modifies the first matching document. update_many() modifies all matches. Always use a $set operator to change specific fields — without it you replace the entire document.
# Update a single document: change the price of "Mouse"
update_result = products.update_one(
{"name": "Mouse"}, # filter
{"$set": {"price": 24.99}} # update
)
print("Matched:", update_result.matched_count,
"Modified:", update_result.modified_count)
# Mark all Acme products as in stock
products.update_many(
{"brand": "Acme"},
{"$set": {"in_stock": True}}
)
# Increment a field value
products.update_one(
{"name": "Laptop"},
{"$inc": {"price": -50}} # reduce price by 50
)Common update operators:
| Operator | Effect |
|---|---|
$set | Set one or more fields |
$unset | Remove a field |
$inc | Increment a numeric field |
$push | Append a value to an array field |
$pull | Remove a value from an array field |
Delete — remove documents
delete_one() removes the first matching document. delete_many() removes all matches.
# Remove a single document
del_result = products.delete_one({"name": "Keyboard"})
print("Deleted count:", del_result.deleted_count)
# Remove all out-of-stock items
products.delete_many({"in_stock": False})
# Confirm what is left
print("Remaining products:")
for p in products.find({}, {"_id": 0, "name": 1}):
print(" -", p["name"])Common Gotchas
Lazy creation can hide typos
Because MongoDB creates databases and collections on demand, a typo silently creates a second, empty database instead of raising an error:
# Intended: client["mystore"] Actual: client["mystoree"]
db = client["mystoree"] # no error, but your data goes to the wrong databaseFix: define database and collection names as module-level constants:
DB_NAME = "mystore"
COL_NAME = "products"
db = client[DB_NAME]
products = db[COL_NAME]Connection errors surface only on first operation
MongoClient() succeeds even when MongoDB is not running. The error appears only when you make an actual request. Use serverSelectionTimeoutMS and a ping check at startup (as shown in the connection section above) to fail fast.
Missing $set replaces the entire document
# WRONG — replaces the whole document with just {"price": 24.99}
products.update_one({"name": "Mouse"}, {"price": 24.99})
# CORRECT — only changes the price field
products.update_one({"name": "Mouse"}, {"$set": {"price": 24.99}})find() returns a cursor, not a list
A cursor is lazy — documents are fetched from the server only as you iterate. If you need a plain list, convert it explicitly:
all_products = list(products.find())Be careful with large collections: fetching everything into memory at once can exhaust RAM.
What is Next
This chapter covered the essentials. The rest of the Python MongoDB series goes deeper on each topic:
- MongoDB Create Database — how lazy creation works and how to verify a database exists.
- MongoDB Create Collection — collection creation options and validation schemas.
- MongoDB Insert —
insert_one(),insert_many(), and handling duplicate key errors. - MongoDB Find — projections, cursors, and sorting.
- MongoDB Query — full reference of query operators.
- MongoDB Update —
update_one(),update_many(),upsert, and array operators. - MongoDB Delete — safe deletion patterns and
drop(). - MongoDB Sort — single-field and multi-field sorting.
- MongoDB Limit — pagination with
limit()andskip(). - MongoDB Drop Collection — removing a collection entirely.