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.
| Method | Returns | Requests | Use when |
|---|---|---|---|
find() | Plain array | One page | You need one explicit page. |
first() | One object or undefined | One page with limit 1 | You need the first match. |
get(id) | One object or rejects | One object request | You know the id. |
count() | Number | Count request | You only need the total. |
findAll() | Plain array | All pages | You intentionally need every match. |
collection().fetch() | Nimbu.Collection | All pages | You need collection helpers/indexing. |
eachBatch() / each() | Promise | Batched requests | You 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.