file-json-db

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).

// 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:

  1. Filter (the query you passed to find)
  2. Sort
  3. Skip
  4. Limit
  5. 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();