Query Builder
When you call collection.find(query) you receive a QueryBuilder
object, not the documents themselves. The builder lets you chain extra operations
(limit, skip, sort, project) before the query is actually executed.
Basic usage
const builder = users.find({ active: true });
// Nothing has been read from disk yet.
// You must call one of the terminal methods:
const docs = builder.toArray(); // array of documents
const first = builder.first(); // first document or null
const total = builder.count(); // number of matching documents
Methods
.limit(n)
Return at most n documents.
users.find({}).limit(10).toArray();
.skip(n)
Skip the first n matching documents (useful for pagination).
// Page 3, 20 items per page
users.find({ active: true })
.skip(40)
.limit(20)
.toArray();
.sort(spec)
Sort the results. The argument is an object whose keys are field names
and whose values are 1 (ascending) or -1 (descending).
// Youngest first
users.find({}).sort({ age: 1 }).toArray();
// Newest posts first, then by title
posts.find({}).sort({ createdAt: -1, title: 1 }).toArray();
Sorting is performed in memory after the matching documents have been collected.
.project(spec)
Include or exclude fields from the returned documents (improved in v1.5.0).
- Inclusion –
{ name: 1, email: 1 }keeps only those fields (+_idby default) - Exclusion –
{ password: 0 }removes the listed fields - Mixed – allowed; exclusion wins
_idis kept by default. Pass_id: 0to hide it.
// Only return name and email (+ _id)
users.find({}).project({ name: 1, email: 1 }).toArray();
// Return everything except the password
users.find({}).project({ password: 0 }).toArray();
// Mixed – exclusion wins for password
users.find({}).project({ name: 1, password: 0, age: 1 }).toArray();
// Hide _id as well
users.find({}).project({ name: 1, _id: 0 }).toArray();
.toArray()
Execute the query and return an array of documents.
.first()
Equivalent to .limit(1).toArray()[0] || null.
.count()
Return the number of matching documents. When possible the library avoids materialising the full result set.
const totalUsers = users.find({}).count();
const activeCount = users.find({ active: true }).count();
Chaining order
You can chain the methods in any order. The logical order of application is:
- Filter (the query you passed to
find) - Sort
- Skip
- Limit
- Project
const page = users
.find({ role: 'member', active: true })
.sort({ createdAt: -1 })
.skip(20)
.limit(10)
.project({ name: 1, email: 1, createdAt: 1 })
.toArray();
Async find
findAsync returns a Promise that resolves to a QueryBuilder.
After that you still call the synchronous terminal methods:
const builder = await users.findAsync({ active: true });
const docs = builder.limit(50).toArray();