Skip to main content

Indexes & explain

Indexes are created per collection field and are persisted on disk.

Create an index

createIndex(collection: string, field: string, options?: { unique?: boolean }): Promise<void>
  • Builds the index from existing documents.
  • After creation, writes keep the index updated.
  • unique: true enforces uniqueness for that field.
import { LioranManager } from "@liorandb/core";

const manager = new LioranManager({ rootPath: "./data" });
const db = await manager.db("app");

db.collection("users"); // ensure collection exists
await db.createIndex("users", "email", { unique: true });

const users = db.collection("users");
console.log(await users.findOne({ email: { $eq: "a@b.com" } }));

await manager.close();

How indexes are used

  • Query execution tries to pick one best index from your query.
  • If no index can be selected, a full scan is used.
  • Even with an index, documents are still re-checked against your full query to ensure correctness.

Supported indexed shapes include:

  • { field: value }
  • { field: { $eq: value } }
  • { field: { $in: [...] } }
  • { field: { $gt/$gte/$lt/$lte: ... } } (range queries)

explain()

You can ask for query plan stats:

db.explain("users", { age: { $gte: 18 } })

The result includes:

  • indexUsed: which field index was used (if any)
  • scannedDocuments: how many documents were read
  • candidateDocuments: how many IDs the index/full-scan produced
  • executionTimeMs: elapsed time in milliseconds