Python Tutorial
Python MongoDB - Find
Read documents with find_one and find, and choose which fields come back.
find_one
find_one returns the first matching document as a dict, or None if nothing matches.
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
customers = client["mydatabase"]["customers"]
doc = customers.find_one() # first document
print(doc)
john = customers.find_one({"name": "John"}) # first matching John
print(john)find Returns a Cursor
find returns a cursor you iterate over. With no argument it returns all documents (like SELECT *).
for doc in customers.find():
print(doc)
for doc in customers.find({"address": "Highway 37"}):
print(doc["name"])Projection: Pick Fields
The second argument controls which fields return. Use 1 to include and 0 to exclude. Turn off _id explicitly if you do not want it.
# include only name and address, hide _id
for doc in customers.find({}, {"_id": 0, "name": 1, "address": 1}):
print(doc)
# exclude just one field
for doc in customers.find({}, {"address": 0}):
print(doc)You cannot mix inclusion and exclusion in the same projection (except for turning off _id). Either list fields to keep, or list fields to drop.
Count and Existence
total = customers.count_documents({}) # all documents
vips = customers.count_documents({"vip": True}) # matching a filter
print(total, vips)
exists = customers.find_one({"name": "Ann"}) is not NoneConvert a Cursor to a List
For small result sets, materialize the cursor into a list. For large ones, iterate to stay memory-friendly.
results = list(customers.find({"vip": True}))
print(len(results))Best Practices
- Use
find_onewhen you expect a single document. - Project only the fields you need to cut network and memory cost.
- Iterate the cursor for large results instead of building a huge list.
- The next lesson covers rich query operators for filtering.
Try It Yourself
Exercise 1: Return only the name field (no _id) for every document.
Show solution
for doc in coll.find({}, {"_id": 0, "name": 1}):
print(doc)Exercise 2: What does find_one return when nothing matches?
Show solution
None.
📘 Real-World Deep Dive
Knowing <strong>MongoDB Find (MongoDB)</strong> well is what turns MongoDB from a curiosity into a daily tool — you'll reach for it in nearly every real project.
Real-Life Scenario
An end-to-end usage of MongoDB Find that you'd actually see in a data pipeline or analytics notebook.
Real-Life Example
from pymongo import MongoClient
db = MongoClient().shop
for u in db.users.find({"active": True}, projection={"email": 1, "_id": 0}).limit(5):
print(u)Expected Output
(see source)Common mistakes
- Inserting a
dictwith embeddeddatetimeworks, but naivedatetime(without UTC) leads to subtle comparison bugs. - Queries with type-mismatched values silently return no results — cast at the boundary or use
bsoncodecs. find()returns a cursor — calllist(cursor)only once you intend to materialise results.- Treating MongoDB Find as a black box without reading the docs — the API has subtle defaults that bite when you scale.
🚀 Performance & Best Practices
- Project only the fields you need:
collection.find({}, {"name": 1}). - Use
bulk_writeinstead of looping over single inserts / updates — order-of-magnitude faster. - Create indexes:
collection.create_index([("field", pymongo.ASCENDING)]). - When working with MongoDB, prefer vectorised / batched operations over Python loops.
🧪 Try It Yourself
- Reproduce the snippet on a representative slice of your own data.
- Profile the snippet with
cProfileortimeitand find the single biggest improvement. - Generalise the snippet into a small, reusable function you can drop into future projects.