API Reference
classes
Modelquerybuilder

@coasys/ad4m / Exports / ModelQueryBuilder

Class: ModelQueryBuilder<T>

Query builder for Ad4mModel queries. Allows building queries with a fluent interface and either running them once or subscribing to updates.

Example

const builder = Recipe.query(perspective)
  .where({ category: "Dessert" })
  .order({ rating: "DESC" })
  .limit(10);
 
// Run once
const recipes = await builder.run();
 
// Or subscribe to updates
await builder.subscribe(recipes => {
  console.log("Updated recipes:", recipes);
});

Type parameters

NameType
Textends Ad4mModel

Table of contents

Constructors

Properties

Methods

Constructors

constructor

new ModelQueryBuilder<T>(perspective, ctor, query?)

Type parameters

NameType
Textends Ad4mModel<T>

Parameters

NameType
perspectivePerspectiveProxy
ctortypeof Ad4mModel
query?Query

Defined in

model/ModelQueryBuilder.ts:43 (opens in a new tab)

Properties

ctor

Private ctor: typeof Ad4mModel

Defined in

model/ModelQueryBuilder.ts:39 (opens in a new tab)


currentSubscription

Private Optional currentSubscription: any

Defined in

model/ModelQueryBuilder.ts:40 (opens in a new tab)


modelClassName

Private modelClassName: string = null

Defined in

model/ModelQueryBuilder.ts:38 (opens in a new tab)


perspective

Private perspective: PerspectiveProxy

Defined in

model/ModelQueryBuilder.ts:36 (opens in a new tab)


queryParams

Private queryParams: Query = {}

Defined in

model/ModelQueryBuilder.ts:37 (opens in a new tab)


useSurrealDBFlag

Private useSurrealDBFlag: boolean = true

Defined in

model/ModelQueryBuilder.ts:41 (opens in a new tab)

Methods

count

count(): Promise<number>

Gets the total count of matching entities.

Returns

Promise<number>

Total count

Example

const totalDesserts = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .count();

Defined in

model/ModelQueryBuilder.ts:430 (opens in a new tab)


countSubscribe

countSubscribe(callback): Promise<number>

Subscribes to count updates for matching entities.

This method:

  1. Creates and initializes a SurrealDB live query subscription for the count (default)
  2. Sets up the callback to process future count updates
  3. Returns the initial count immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
callback(count: number) => voidFunction to call with updated count

Returns

Promise<number>

Initial count

Example

const builder = Recipe.query(perspective)
  .where({ status: "active" });
 
const initialCount = await builder.countSubscribe(count => {
  console.log("Active items:", count);
});
 
// When done with subscription:
builder.dispose();

Remarks

By default, this uses SurrealDB live queries for real-time updates. Prolog subscriptions remain available via .useSurrealDB(false).

Defined in

model/ModelQueryBuilder.ts:477 (opens in a new tab)


dispose

dispose(): void

Disposes of the current subscription if one exists.

This method:

  1. Stops the keepalive signals to the subscription
  2. Unsubscribes from GraphQL subscription updates
  3. Notifies the backend to clean up subscription resources
  4. Clears the subscription reference

You should call this method when you're done with a subscription to prevent memory leaks and ensure proper cleanup.

Returns

void

Defined in

model/ModelQueryBuilder.ts:61 (opens in a new tab)


first

first(): Promise<T>

Returns the first matching instance, or null if none match.

Internally sets limit: 1 and delegates to get().

Returns

Promise<T>

The first matching instance, or null

Example

const recipe = await Recipe.query(perspective)
  .where({ name: "Pasta" })
  .first();

Defined in

model/ModelQueryBuilder.ts:334 (opens in a new tab)


get

get(): Promise<T[]>

Executes the query once and returns the results.

Returns

Promise<T[]>

Array of matching entities

Example

const recipes = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .get();

Defined in

model/ModelQueryBuilder.ts:305 (opens in a new tab)


include

include(map): ModelQueryBuilder<T>

Specifies which relations to eager-load (hydrate into model instances).

Without include, relation fields contain raw expression URIs (strings). With include, the URIs are resolved into fully-hydrated model instances using the target class declared in the relation decorator.

Supports nested includes for multi-level eager loading.

Parameters

NameTypeDescription
mapIncludeMapAn IncludeMap describing which relations to hydrate

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

// Hydrate comments one level deep
const recipes = await Recipe.query(perspective)
  .include({ comments: true })
  .run();
// recipe.comments is now Comment[] (model instances), not string[]
 
// Nested: hydrate comments AND each comment's author
const recipes = await Recipe.query(perspective)
  .include({ comments: { author: true } })
  .run();

Defined in

model/ModelQueryBuilder.ts:253 (opens in a new tab)


limit

limit(limit): ModelQueryBuilder<T>

Sets the maximum number of results to return.

Parameters

NameTypeDescription
limitnumberMaximum number of results

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.limit(10)

Defined in

model/ModelQueryBuilder.ts:116 (opens in a new tab)


offset

offset(offset): ModelQueryBuilder<T>

Sets the number of results to skip.

Parameters

NameTypeDescription
offsetnumberNumber of results to skip

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.offset(20) // Skip first 20 results

Defined in

model/ModelQueryBuilder.ts:132 (opens in a new tab)


order

order(orderBy): ModelQueryBuilder<T>

Sets the order for the query results.

Parameters

NameTypeDescription
orderByOrderThe ordering criteria

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.order({ createdAt: "DESC" })

Defined in

model/ModelQueryBuilder.ts:100 (opens in a new tab)


overrideModelClassName

overrideModelClassName(className): ModelQueryBuilder<T>

Parameters

NameType
classNamestring

Returns

ModelQueryBuilder<T>

Defined in

model/ModelQueryBuilder.ts:258 (opens in a new tab)


paginate

paginate(pageSize, pageNumber): Promise<PaginationResult<T>>

Gets a page of results with pagination metadata.

Parameters

NameTypeDescription
pageSizenumberNumber of items per page
pageNumbernumberWhich page to retrieve (1-based)

Returns

Promise<PaginationResult<T>>

Paginated results with metadata

Example

const page = await Recipe.query(perspective)
  .where({ category: "Main" })
  .paginate(10, 1);
console.log(`Page ${page.pageNumber}, ${page.results.length} of ${page.totalCount}`);

Defined in

model/ModelQueryBuilder.ts:529 (opens in a new tab)


paginateSubscribe

paginateSubscribe(pageSize, pageNumber, callback): Promise<PaginationResult<T>>

Subscribes to paginated results updates.

This method:

  1. Creates and initializes a SurrealDB live query subscription for the paginated results (default)
  2. Sets up the callback to process future page updates
  3. Returns the initial page immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
pageSizenumberNumber of items per page
pageNumbernumberWhich page to retrieve (1-based)
callback(results: PaginationResult<T>) => voidFunction to call with updated pagination results

Returns

Promise<PaginationResult<T>>

Initial pagination results

Example

const builder = Recipe.query(perspective)
  .where({ category: "Main" });
 
const initialPage = await builder.paginateSubscribe(10, 1, page => {
  console.log("Updated page:", page.results);
});
 
// When done with subscription:
builder.dispose();

Remarks

By default, this uses SurrealDB live queries for real-time updates. Prolog subscriptions remain available via .useSurrealDB(false).

Defined in

model/ModelQueryBuilder.ts:577 (opens in a new tab)


parent

parent(idOrInstance, modelOrPredicate?, options?): ModelQueryBuilder<T>

Scopes the query to instances linked from a parent.

The predicate is resolved in order of precedence:

  1. Instance only — the parent's constructor is used as the model class; its relation metadata is scanned for a relation whose target() matches the queried model class.
  2. Instance + options with field — direct field-name lookup on the parent model's relation metadata (disambiguates when a parent has multiple relations targeting the same child class).
  3. String id + model class — same metadata scan (or field lookup if options include field).
  4. String id + string predicate — raw escape hatch, no metadata lookup.

Passing a plain string id with no second argument throws because the predicate cannot be resolved without a model class.

Parameters

NameTypeDescription
idOrInstancestring | Ad4mModelThe parent's expression URI or an Ad4mModel instance
modelOrPredicate?string | typeof Ad4mModel | { field: string }A model class (predicate auto-resolved) or a raw predicate string
options?ObjectOptional settings: field for direct relation-name lookup
options.field?string-

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

// Instance — predicate auto-resolved from Cookbook's @HasMany(() => Recipe)
Recipe.query(perspective).parent(cookbook).get();
 
// Instance + field — disambiguate when parent has multiple relations to same child
Recipe.query(perspective).parent(cookbook, { field: "recipes" }).get();
 
// String id + model class
Recipe.query(perspective).parent(cookbookId, Cookbook).get();
 
// String id + model class + field
Recipe.query(perspective).parent(cookbookId, Cookbook, { field: "recipes" }).get();
 
// String id + raw predicate (escape hatch)
Recipe.query(perspective).parent(cookbookId, "cookbook://recipe").get();

Defined in

model/ModelQueryBuilder.ts:177 (opens in a new tab)


properties

properties(properties): ModelQueryBuilder<T>

Specifies which properties to include in the results.

Parameters

NameTypeDescription
propertiesstring[]Array of property names to include

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.properties(["name", "description", "rating"])

Defined in

model/ModelQueryBuilder.ts:222 (opens in a new tab)


subscribe

subscribe(callback): Promise<T[]>

Subscribes to the query and receives updates when results change.

This method:

  1. Creates and initializes a SurrealDB live query subscription (default)
  2. Sets up the callback to process future updates
  3. Returns the initial results immediately

Remember to call dispose() when you're done with the subscription to clean up resources.

Parameters

NameTypeDescription
callback(results: T[]) => voidFunction to call with updated results

Returns

Promise<T[]>

Initial results array

Example

const builder = Recipe.query(perspective)
  .where({ status: "cooking" });
 
const initialRecipes = await builder.subscribe(recipes => {
  console.log("Updated recipes:", recipes);
});
 
// When done with subscription:
builder.dispose();

Remarks

By default, this uses SurrealDB live queries for real-time updates. Prolog subscriptions remain available via .useSurrealDB(false).

Defined in

model/ModelQueryBuilder.ts:371 (opens in a new tab)


useSurrealDB

useSurrealDB(enabled?): ModelQueryBuilder<T>

Enables or disables SurrealDB query path.

Parameters

NameTypeDefault valueDescription
enabledbooleantrueWhether to use SurrealDB (default: true, 10-100x faster) or Prolog (legacy)

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

// Use SurrealDB (default)
const recipes = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .useSurrealDB(true)
  .get();
 
// Use Prolog (legacy)
const recipesProlog = await Recipe.query(perspective)
  .where({ category: "Dessert" })
  .useSurrealDB(false)
  .get();

Remarks

Note: Subscriptions (subscribe(), countSubscribe(), paginateSubscribe()) default to SurrealDB live queries if useSurrealDB(true) is set (default).

Defined in

model/ModelQueryBuilder.ts:288 (opens in a new tab)


where

where(conditions): ModelQueryBuilder<T>

Adds where conditions to the query.

Parameters

NameTypeDescription
conditionsWhereThe conditions to filter by

Returns

ModelQueryBuilder<T>

The query builder for chaining

Example

.where({
  category: "Dessert",
  rating: { gt: 4 },
  tags: ["vegan", "quick"],
  published: true
})

Defined in

model/ModelQueryBuilder.ts:84 (opens in a new tab)