find / findOne
The find() method runs a query and returns a cursor. Combined with projections, sort, limit, and skip, it covers 80% of read patterns — with indexes doing the heavy lifting.
Filters, projections, cursor patterns
EXAMPLE
// 1) Filter — equality
await db.users.findOne({ email: 'ada@example.com' });
await db.users.find({ status: 'active' }).toArray();
// 2) Comparison operators
await db.orders.find({ total: { $gt: 100 } }).toArray();
await db.orders.find({ total: { $gte: 100, $lt: 500 } }).toArray();
await db.users.find({ age: { $in: [18, 21, 25] } }).toArray();
await db.users.find({ role: { $ne: 'admin' } }).toArray();
// 3) Existence / type
await db.users.find({ deletedAt: { $exists: false } }).toArray();
await db.events.find({ payload: { $type: 'object' } }).toArray();
// 4) Logical — $and (implicit), $or, $nor
await db.posts.find({
status: 'published',
$or: [
{ category: 'news' },
{ tags: 'featured' },
],
}).toArray();
// 5) Array queries
await db.users.find({ tags: 'newsletter' }).toArray(); // tags contains 'newsletter'
await db.users.find({ tags: { $all: ['vip', 'beta'] } }).toArray(); // contains BOTH
await db.orders.find({ 'items.sku': 'A-100' }).toArray(); // any item has sku
await db.orders.find({ items: { $size: 0 } }).toArray(); // empty array
// 6) Element-match — array element matching ALL conditions
await db.orders.find({
items: { $elemMatch: { sku: 'A-100', qty: { $gte: 5 } } },
}).toArray();
// 7) Regex
await db.users.find({ email: { $regex: /@example\.com$/i } }).toArray();
// 8) Projection — return only the fields you need
await db.users.find({}, { projection: { name: 1, email: 1, _id: 0 } }).toArray();
await db.posts.find({}, { projection: { body: 0 } }).toArray(); // exclude one field
// 9) Cursor methods
await db.posts.find({ status: 'published' })
.sort({ createdAt: -1 })
.skip(40)
.limit(20)
.toArray();
// 10) Stream large results — never load to memory
const cursor = db.events.find({});
for await (const doc of cursor) {
await process(doc); // backpressure-aware
}
// 11) Count
await db.users.countDocuments({ status: 'active' });
// estimatedDocumentCount() is faster but only the total
// 12) Explain — what index is it using?
await db.posts.find({ status: 'published' }).sort({ createdAt: -1 }).explain('executionStats');
Why it matters
Use countDocuments for filtered counts; estimatedDocumentCount for whole-collection. The latter reads metadata in milliseconds; the former runs a real query.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
db.customers.findOne({ name: 'Ada' });
db.customers.find({ age: { $gte: 30 } });
Try it Yourself »
Exercise
Find every active user.
db.users.find({ active:
});
Four letters.
Discussion
Loading…