Skip to content
🚀 This documentation is for unreal-orm 1.0.0 alpha which requires SurrealDB 2.0 SDK. For use with version 1.x, see here.

Indexes

Indexes are defined separately from tables and passed to applySchema alongside the model classes. Use Index.define and pass a thunk that returns the target model; this avoids circular import problems.

import { Index } from 'unreal-orm';
import { User } from './User';
const UserEmailIndex = Index.define(() => User, {
name: 'user_email_idx',
fields: ['email'],
unique: true,
});
Index.define(() => User, {
name: 'user_email_idx',
fields: ['email'],
unique: true,
concurrently: true, // CREATE INDEX ... CONCURRENTLY
defer: false, // defer index updates to a background queue
comment: 'Unique email index',
})
Option Purpose
name Index name in the database.
fields Array of field names to index.
unique Enforce uniqueness across the indexed columns.
count Build a COUNT index for fast count() queries.
search Build a full-text SEARCH index.
analyzer Analyzer to use with a search index.
bm25 Enable BM25 ranking on a search index.
highlights Enable keyword highlighting on a search index.
concurrently Create the index without blocking writes.
defer Use a background queue for index updates.
comment Optional index comment.
const UserNameIndex = Index.define(() => User, {
name: 'user_name_idx',
fields: ['firstName', 'lastName'],
unique: true,
});
const PostContentIndex = Index.define(() => Post, {
name: 'post_content_idx',
fields: ['title', 'content'],
search: true,
analyzer: 'english',
bm25: true,
});

Use the index in a query:

const results = await Post.select(db, {
where: surql`title @@ 'database' OR content @@ 'database'`,
});

See the Full-Text Search guide for a deeper dive.

Vector indexes enable efficient k-nearest-neighbor (kNN) similarity search on high-dimensional vector embeddings. UnrealORM supports three algorithms:

Algorithm Best for Storage
MTREE Smaller datasets, exact distance In-memory
HNSW Low-latency ANN, graph fits in memory In-memory graph + persistence
DISKANN Very large corpora, RAM-limited (SurrealDB 3.1+) Key-value-backed graph + bounded cache
const EmbeddingIndex = Index.define(() => Document, {
name: 'doc_embedding_hnsw',
fields: ['embedding'],
vector: {
type: 'HNSW',
dimension: 768,
distance: 'COSINE',
elementType: 'F32',
efc: 200, // EF construction (default: 150)
m: 16, // Max connections per element (default: 12)
m0: 32, // Max connections in lowest layer (default: 24)
},
});
const EmbeddingIndex = Index.define(() => Document, {
name: 'doc_embedding_mtree',
fields: ['embedding'],
vector: {
type: 'MTREE',
dimension: 768,
distance: 'COSINE',
elementType: 'F32',
},
});
const EmbeddingIndex = Index.define(() => Document, {
name: 'doc_embedding_diskann',
fields: ['embedding'],
vector: {
type: 'DISKANN',
dimension: 768,
distance: 'EUCLIDEAN',
elementType: 'F32',
degree: 64, // Target max graph degree (default: 64)
lBuild: 100, // Construction search-list size (default: 100)
alpha: 1.2, // Pruning parameter (default: 1.2)
hashedVector: true, // Hash-stabilised vector-document keys
},
});
Option Applies to Description
type All Algorithm: 'MTREE', 'HNSW', or 'DISKANN'
dimension All Vector dimension (number of elements)
elementType All Vector type: 'F64', 'F32', 'F16', 'I64', 'I32', 'I16', 'I8', 'U8'
distance All Distance metric: 'EUCLIDEAN', 'COSINE', 'MANHATTAN', 'INNER_PRODUCT', 'COSINE_NORMALIZED', 'HAMMING'
efc HNSW EF construction (default: 150)
m HNSW Max connections per element (default: 12)
m0 HNSW Max connections in lowest layer (default: 24)
lm HNSW Level generation multiplier (auto-computed by default)
degree DISKANN Target max graph degree (default: 64)
lBuild DISKANN Construction search-list size (default: 100)
alpha DISKANN Pruning parameter (default: 1.2)
hashedVector DISKANN Enable hash-stabilised vector-document keys