Querying
GraphDB provides two synchronous methods for querying documents: query() which returns an array of matching documents, and findOne() which returns the first match or null.
All examples below use this setup:
import { GraphDB } from "@graphdb/core";
type User = { name: string; email: string; age: number;};
const db = GraphDB();const users = db.createCollection<User>("users");
await users.create({ name: "Alex", email: "alex@example.com", age: 30 });await users.create({ name: "Sam", email: "sam@example.com", age: 25 });await users.create({ name: "Jordan", email: "jordan@example.com", age: 35 });query()
query() is synchronous and always returns Doc<User>[] — never null. If nothing matches, it returns an empty array.
const results = users.query({ age: { gte: 30 } });// [Doc<User>, Doc<User>] -- Alex and JordanPass an empty object to get all documents:
const all = users.query({});findOne()
findOne() is synchronous and returns Doc<User> | null. It returns the first document that matches the where clause.
const user = users.findOne({ name: "Alex" });// Doc<User> | nullPrimitive equality
The simplest form of a where clause uses direct value matching:
const results = users.query({ name: "Alex" });This matches documents where name is exactly "Alex".
RegExp matching
You can use a RegExp directly at the top level of a where clause:
const results = users.query({ name: /alex/i });Or use the match operator for the same effect:
const results = users.query({ name: { match: /alex/i } });Operators
eq
Strict equality check:
users.query({ age: { eq: 30 } });notEq
Not equal:
users.query({ age: { notEq: 30 } });// Sam (25) and Jordan (35)gt
Greater than:
users.query({ age: { gt: 25 } });// Alex (30) and Jordan (35)gte
Greater than or equal:
users.query({ age: { gte: 30 } });// Alex (30) and Jordan (35)lt
Less than:
users.query({ age: { lt: 30 } });// Sam (25)lte
Less than or equal:
users.query({ age: { lte: 30 } });// Sam (25) and Alex (30)includes
Check if a string field contains a substring:
users.query({ email: { includes: "example" } });// All usersstartsWith
Check if a string field starts with a prefix:
users.query({ name: { startsWith: "Al" } });// AlexendsWith
Check if a string field ends with a suffix:
users.query({ email: { endsWith: ".com" } });// All usersmatch
Match against a regular expression:
users.query({ name: { match: /^[AJ]/ } });// Alex and Jordanin
Match any value in an array:
users.query({ age: { in: [25, 35] } });// Sam (25) and Jordan (35)Multi-field where clauses
You can combine multiple fields in a single where clause. A document must match all conditions:
const results = users.query({ age: { gte: 25 }, name: { startsWith: "A" },});// Only Alex matches both conditionsQuery options
The second argument to query() is an optional QueryOptions object with orderBy, skip, and limit.
const results = users.query({ age: { gte: 20 } }, { orderBy: { age: "DESC" }, skip: 0, limit: 2,});See the Sorting & Pagination guide for full details on these options.
Pipeline order
Queries execute in a fixed order:
- Filter — apply the where clause to select matching documents
- Sort — order the results by
orderByfields - Skip — skip the first N results
- Limit — take at most N results from what remains
This means sorting happens on the full filtered set before pagination is applied, giving you predictable paginated results.