100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
MongoDB

Querying Documents

Learn how to retrieve documents from MongoDB collections using find() and findOne(), filters, projections, and cursor methods.

CRUD OperationsBeginner9 min readJul 10, 2026
Analogies

Retrieving Documents with find()

db.collection.find(filter, projection) is the core read operation in MongoDB. Called with no arguments, find() returns every document in the collection as a cursor; passing a filter object narrows results to documents matching those field-value pairs, and the query engine can use indexes to satisfy the filter without scanning the whole collection.

🏏

Cricket analogy: It is like asking a scorer for every ball bowled in a match versus asking only for deliveries bowled by Jasprit Bumrah — the narrower filter returns a focused subset instead of the full innings log.

findOne() and Cursor Methods

findOne(filter) returns the first matching document directly, not a cursor, which is convenient when you expect at most one result, such as a lookup by a unique field. find() itself returns a cursor that is lazily evaluated; chaining .sort(), .limit(), and .skip() lets you control ordering and pagination before the cursor is actually iterated with .toArray(), forEach(), or a for-await loop.

🏏

Cricket analogy: It is like asking the scorer for just the current striker's stats rather than the whole team sheet — findOne() hands you a single record directly instead of a list you'd have to page through.

Projections: Shaping the Returned Fields

The second argument to find() and findOne() is a projection that controls which fields are returned. Passing { name: 1, price: 1 } includes only those fields (plus _id unless explicitly excluded with _id: 0), while passing { description: 0 } excludes just that field and returns everything else. You cannot mix inclusion and exclusion in the same projection except for _id.

🏏

Cricket analogy: It is like requesting only a player's runs and strike rate from the full scorecard rather than every statistic recorded — a projection trims the response to just what you need.

javascript
// Find in-stock products under $50, sorted by price, projecting only name and price
db.products.find(
  { inStock: true, price: { $lt: 50 } },
  { name: 1, price: 1, _id: 0 }
)
  .sort({ price: 1 })
  .limit(10);

// Find a single product by its unique SKU
db.products.findOne({ sku: "MOU-2024-BLK" });

A cursor returned by find() is lazy: MongoDB does not fetch all matching documents at once. It batches results from the server as you iterate, which is why chaining .sort(), .skip(), and .limit() before iteration is efficient — the server can apply them before sending data over the wire.

Query Performance and Explain Plans

Running .explain('executionStats') on a query reveals whether MongoDB used an index (IXSCAN) or scanned every document (COLLSCAN), along with the number of documents examined versus returned. A query that examines far more documents than it returns is a strong signal that a supporting index is missing, which becomes critical as collections grow past a few thousand documents.

🏏

Cricket analogy: It is like checking whether the analyst pulled Virat Kohli's batting stats from an indexed player database or manually scanned every ball of every match ever played — the indexed lookup is dramatically faster.

Calling .sort() on a field without a supporting index forces MongoDB to load all matching documents into memory to sort them, which can hit the 100MB memory limit for sort operations and throw an error unless allowDiskUse is enabled or an index backs the sort field.

  • find(filter, projection) returns a cursor over matching documents; findOne() returns a single document directly.
  • An empty filter {} matches every document in the collection.
  • Projections control which fields are returned; you can't mix inclusion and exclusion except for _id.
  • Cursors are lazy and support chaining .sort(), .skip(), and .limit() before iteration.
  • .explain('executionStats') reveals whether a query used an index (IXSCAN) or a full scan (COLLSCAN).
  • Sorting on an unindexed field can hit MongoDB's in-memory sort limit on large result sets.
  • Queries that examine far more documents than they return usually need a supporting index.

Practice what you learned

Was this page helpful?

Topics covered

#MongoDB#MongoDBStudyNotes#Database#QueryingDocuments#Querying#Documents#Retrieving#Find#StudyNotes#SkillVeris