Nimbu Developer Docs

Queries

Filter, sort, paginate, count, and batch process Nimbu data with Nimbu.Query.

Nimbu.Query finds objects by class or channel name.

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

You can pass a subclass too:

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

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

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.

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:

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

Constraints

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:

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

Geo helpers:

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

Sorting And Projection

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

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

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.

On this page