[data-reveal]{opacity:1!important;transform:none!important}
Query Types
Database

Query Types

AQL provides several query classes that form a hierarchy of capabilities. Each class encapsulates a different aspect of database interactions, from full table access down to individual value manipulation.

Choose by the result you need

You are working with…TypeTypical next operation
A whole tableTable<T>Insert a record or select by key.
Several writable recordsSelection<T>Update or delete the selection.
One writable recordSingleSelection<T>Read, update, or delete by key.
A sequence of query resultsStream<T>Map, sort, aggregate, or paginate.
One query resultDatum<T>Read a field or transform the value.
A value inside a query callbackValueProxy<T>Build an expression with eq, add, or other query operators.

ValueProxy describes database expressions; it is not the fetched JavaScript value. Use its operators inside query callbacks, then execute the outer query to obtain data.

Query Type Hierarchy

All query types inherit from StagedObject, which records operations as a pipeline of stages. The hierarchy is:

Query<T>
├── Datum<T>
│   └── SingleSelection<T>
└── Stream<T>
    └── Selection<T>
        └── Table<T>

ValueProxy<T> (used within query callbacks)

Common Features

All query types that extend Query<T> share these capabilities:

  • run() - Execute the query and return a Promise<T> with the result.
  • then() - PromiseLike support, so queries can be awaited directly.
  • cursor() - Return an AsyncGenerator for streaming results one at a time.
  • [Symbol.asyncIterator]() - Enable for await...of loops over query results.
import { Schema } from "@antelopejs/interface-database";

// Execute a query explicitly
const result = await schema.instance().table("users").run();

// Await the query directly (uses PromiseLike)
const users = await schema.instance().table("users");

// Iterate with async generator
for await (const user of schema.instance().table("users")) {
  console.log(user.name);
}

Recognize a Query Type

IsQuery, IsDatum, IsStream and IsValueProxy tell what kind of staged object a value is:

import { IsStream } from "@antelopejs/interface-database";

function describe(query: unknown) {
  return IsStream(query) ? "a sequence of documents" : "a single value";
}

Each provider binding of the interface has its own copy of these classes, so a query built by a module bound to another database is not an instanceof this module's Stream. The predicates recognize it whichever copy built it. Keep instanceof for checking that a query was built for this module's own binding.

Available Query Types

  • Table - Represents a database table with insert, get, getAll, and between operations
  • Selection - A set of documents supporting update, replace, and delete
  • SingleSelection - A single document with update, replace, delete, and change feed support
  • Stream - A sequence of results with map, filter, join, group, aggregate, and sort operations
  • Change Feeds - Real-time change notifications via the changes() method
  • Query - The base class providing execution and async iteration
  • Datum - A single value with field access, transformation, and lookup capabilities
  • ValueProxy - Proxy for in-query value operations (arithmetic, string, date, array, object)