Index Management
Define Indexes in a Schema
Indexes are declared in the indexes property of each table definition:
import { Schema } from "@antelopejs/interface-database";
const schema = new Schema("myapp", {
users: {
fields: { name: "string", email: "string", role: "string", age: "number" },
indexes: {
email: {}, // Simple index on the "email" field
role: {}, // Simple index on the "role" field
name_age: { fields: ["name", "age"] }, // Compound index
},
},
});
IndexDefinition
interface IndexDefinition {
fields?: string[]; // Fields for compound indexes (omit for single-field)
multi?: boolean; // Whether this is a multi-valued index
crossInstance?: boolean; // Also serve CROSS_INSTANCE queries efficiently
}
When fields is omitted, the index name is used as the field name. For compound indexes, provide the fields array explicitly.
Use Indexes for Queries
getAll() with an Index
Retrieve documents by index value:
const db = schema.instance();
const users = db.table("users");
// Query by the "role" index
const admins = await users.getAll("admin", "role");
// Query multiple values
const targets = await users.getAll(["admin", "moderator"], "role");
between() with an Index
Retrieve documents where the index value falls within a range:
const results = await users.between("age", 18, 65);
orderBy() with an Index
Sort results using an indexed field for better performance:
const sorted = await users.orderBy("email", "asc");
const newest = await users.orderBy("createdAt", "desc");
Compound Indexes
Compound indexes span multiple fields. Define them with the fields array:
const schema = new Schema("blog", {
posts: {
fields: {
category: "string",
publishedAt: "date",
title: "string",
},
indexes: {
category_date: { fields: ["category", "publishedAt"] },
},
},
});
Compound indexes support prefix-based lookups. You can query by the first field alone or by both fields together.
Multi Indexes
Set multi: true for fields that contain arrays. The database creates an index entry for each element in the array, enabling lookups by any single element:
const schema = new Schema("content", {
articles: {
fields: { tags: ["string"] },
indexes: {
tags: { multi: true },
},
},
});
Cross-Instance Indexes
Indexes are optimized for queries scoped to one instance (schema.instance(id)). Queries run with schema.instance(CROSS_INSTANCE) can still use them, but may be slow. Set crossInstance: true on the indexes that cross-instance queries rely on, and the driver also maintains an index usable by those queries:
const schema = new Schema("billing", {
invoices: {
fields: { status: "string" },
indexes: {
status: { crossInstance: true },
},
},
});
// Efficient on every instance at once
await schema
.instance(CROSS_INSTANCE)
.table("invoices")
.getAll("unpaid", "status");
The flag defaults to false. It never changes query results, only performance. Each flagged index costs extra storage and write overhead, so only set it where cross-instance queries use the index.
Index Design Guidelines
- Index fields used in
getAll()andbetween()calls for best performance. - Compound indexes are useful when you frequently filter or sort by multiple fields together.
- Avoid over-indexing. Each index adds storage overhead and slows down writes.
- Filter early in your query chain to reduce the number of documents processed.
CRUD Operations
CRUD operations (Create, Read, Update, Delete) form the foundation of document management in AQL. All examples assume a schema is already defined and an instance is available.
Filtering and Querying
This guide covers techniques for selecting, comparing, and transforming documents using AQL's filter and ValueProxy capabilities.