// Signature
db.collection.find(query, projection, options)
// All documents in collection
db.users.find({})
// Filter: exact match
db.users.find({ city: "Mumbai" })
// Filter: range with comparison operators
db.products.find({ price: { $gt: 100, $lte: 500 } })
// Filter: logical OR
db.users.find({ $or: [{ city: "Mumbai" }, { city: "Delhi" }] })
find() Returns a Cursor — Not Data
// Cursor is ALWAYS truthy — even with 0 results
const cur = db.users.find({ name: "Ghost" })
if (cur) { ... } // always enters — cursor object is truthy regardless
// CORRECT ways to check if results exist:
cur.hasNext() // true if at least one document remains
cur.toArray().length // convert first, then check length
db.users.countDocuments({ name: "Ghost" }) // modern way to count
// Convert to array (loads all into memory — avoid on large sets)
const docs = db.users.find({}).toArray()
// Iterate with forEach (memory-efficient — processes one at a time)
db.users.find({}).forEach(doc => {
print(doc.name)
})
Cursor Batch Size
MongoDB fetches results in batches — first batch is 101 documents (or 1MB, whichever is smaller). Subsequent getMore ops fetch up to 16MB. This keeps memory usage low on large collections.
find({}) on an empty collection returns an empty cursor — it does not throw an error or return null.