Skip to content

Queries

Nimbu.Query finds objects by class or channel name.

js
const query = new Nimbu.Query('articles');
query.equalTo('published', true);

You can pass a subclass too:

js
const Article = Nimbu.Object.extend('articles');
const query = new Nimbu.Query(Article);

Execute Queries

Use the execution method that matches the amount of data you need.

MethodReturnsRequestsUse when
find()Plain arrayOne pageYou need one explicit page.
first()One object or undefinedOne page with limit 1You need the first match.
get(id)One object or rejectsOne object requestYou know the id.
count()NumberCount requestYou only need the total.
findAll()Plain arrayAll pagesYou intentionally need every match.
collection().fetch()Nimbu.CollectionAll pagesYou need collection helpers/indexing.
eachBatch() / each()PromiseBatched requestsYou need to process many records safely.

One Page

js
const articles = await new Nimbu.Query('articles')
  .equalTo('published', true)
  .descending('published_at')
  .limit(20)
  .find();

Always set limit() when using find() for list views. Without it, the backend default page size applies.

All Matches

js
const articles = await new Nimbu.Query('articles')
  .equalTo('status', 'scheduled')
  .findAll({ batchSize: 100 });

Use this for bounded sets. For large sync jobs, prefer batch iteration.

Batch Processing

eachBatch() walks matching objects by id. Do not combine it with sort, skip, or limit.

js
const query = new Nimbu.Query('orders');
query.equalTo('status', 'paid');

await query.eachBatch(async (orders) => {
  for (const order of orders) {
    order.set('exported', true);
    await order.save();
  }
}, { batchSize: 100 });

each() is similar but calls your callback once per object:

js
await query.each(async (order) => {
  await exportOrder(order);
}, { batchSize: 100 });

Constraints

js
query.equalTo('status', 'published');
query.notEqualTo('archived', true);
query.greaterThan('views', 100);
query.greaterThanOrEqualTo('rating', 4);
query.lessThan('price', 50);
query.lessThanOrEqualTo('stock', 10);
query.containedIn('status', ['draft', 'scheduled']);
query.notContainedIn('status', ['deleted']);
query.containsAll('tags', ['public', 'featured']);
query.exists('title');
query.doesNotExist('deleted_at');

Text helpers:

js
query.contains('title', 'guide');
query.startsWith('slug', 'news-');
query.endsWith('email', '@example.com');
query.matches('slug', /^news/i);
query.search('solar panels');

Geo helpers:

js
query.geoWithin('location', polygon);
query.geoIntersects('area', geometry);
query.nearCoordinates('pin', 4.35, 50.85, 1000);

Sorting And Projection

js
query.ascending('title');
query.descending('published_at');
query.addAscending('slug');
query.addDescending('updated_at');

query.include('author', 'category');
query.only('title', 'slug', 'published_at');

include() resolves related objects. only() limits returned fields.

Manual Pagination

js
const page = 2;
const perPage = 25;

const query = new Nimbu.Query('articles');
query.equalTo('published', true);
query.page(page);
query.per(perPage);

const articles = await query.find();
const total = await query.count();

The SDK tracks hasNext(), next(), hasPrevious(), and prev() from API pagination headers after a find().

OR Queries

js
const draft = new Nimbu.Query('articles').equalTo('status', 'draft');
const scheduled = new Nimbu.Query('articles').equalTo('status', 'scheduled');

const query = Nimbu.Query.or(draft, scheduled);
const articles = await query.findAll();

All queries in an OR query must target the same class/channel.

Part of Nimbu, built by Zenjoy.