WHERE Operators
Full reference for filter operators available in Jazz query builders, with examples for each column kind.Operator reference by column type
Operator support by column type (TypeScript):
| Column kind | Operators / shape |
|---|---|
id | eq, ne, in |
s.string() | eq, ne, contains, in |
s.boolean() | eq, ne, in |
s.int() / s.float() | eq, ne, gt, gte, lt, lte, in |
s.timestamp() | eq, ne, gt, gte, lt, lte, in |
s.bytes() | eq, ne, in |
s.uuid() (required) | eq, ne, in |
s.uuid().optional() | eq, ne, in, isNull |
s.enum(...) | eq, ne, in |
s.array(...) | eq, contains, in |
s.json() / s.json(schema) | eq, ne, in |
Nullable columns with ordinary filter operators also support isNull. Required columns, id, and payload enums do not expose it.
Examples
Equality and inequality
// Exact match (shorthand — no operator object needed)const incompleteTodos = await db.all(app.todos.where({ done: false }));// Not equalconst nonDraftTodos = await db.all(app.todos.where({ title: { ne: "Draft" } }));// One of a setconst selectedTodos = await db.all(app.todos.where({ id: { in: [todoIdA, todoIdB] } }));
// Exact match (shorthand — no operator object needed)const incompleteTodos = yield* jazz.all(app.todos.where({ done: false }));// Not equalconst nonDraftTodos = yield* jazz.all(app.todos.where({ title: { ne: "Draft" } }));// One of a setconst selectedTodos = yield* jazz.all(app.todos.where({ id: { in: [todoIdA, todoIdB] } }));
// Exact matchlet query = Query::from("todos").filter(eq(col("done"), lit(false)));let incomplete_todos = client.query(query, None).await?;// Not equallet query = Query::from("todos").filter(ne(col("title"), lit("Draft")));let non_draft_todos = client.query(query, None).await?;
Numeric comparisons
const oneWeekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;const recentTodos = await db.all(app.todos.where({ $createdAt: { gt: oneWeekAgo } }));const highPriority = await db.all(app.todos.where({ priority: { gte: 3 } }));const lowPriority = await db.all(app.todos.where({ priority: { lt: 10 } }));
const oneWeekAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;const recentTodos = yield* jazz.all(app.todos.where({ $createdAt: { gt: oneWeekAgo } }));const highPriority = yield* jazz.all(app.todos.where({ priority: { gte: 3 } }));const lowPriority = yield* jazz.all(app.todos.where({ priority: { lt: 10 } }));
let now_ms = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as u64;let one_week_ago = now_ms - 7 * 24 * 60 * 60 * 1000;let query = Query::from("todos").filter(gt(col("$createdAt"), lit(one_week_ago)));let recent_todos = client.query(query, None).await?;let query = Query::from("todos").filter(gte(col("priority"), lit(3)));let high_priority = client.query(query, None).await?;let query = Query::from("todos").filter(lt(col("priority"), lit(10)));let low_priority = client.query(query, None).await?;
String contains
// Substring match (case-sensitive)const matches = await db.all(app.todos.where({ title: { contains: searchTerm } }));
// Substring match (case-sensitive)const matches = yield* jazz.all(app.todos.where({ title: { contains: searchTerm } }));
// Substring match (case-sensitive)let query = Query::from("todos").filter(contains(col("title"), lit(search_term)));let matches = client.query(query, None).await?;
Null checks on optional columns
In TypeScript, isNull: true matches missing values and isNull: false matches present values. Nullable columns with ordinary filter operators support it, including scalar and array columns, not just references; required columns and payload enums do not expose it.
// Rows where the optional ref is not setconst unlinkedTodos = await db.all(app.todos.where({ parentId: { isNull: true } }));// Rows where it is setconst linkedTodos = await db.all(app.todos.where({ parentId: { isNull: false } }));
// Rows where the optional ref is not setconst unlinkedTodos = yield* jazz.all(app.todos.where({ parentId: { isNull: true } }));// Rows where it is setconst linkedTodos = yield* jazz.all(app.todos.where({ parentId: { isNull: false } }));
// Rows where the optional ref is not setlet query = Query::from("todos").filter(is_null(col("parent")));let unlinked_todos = client.query(query, None).await?;// Rows where it is setlet query = Query::from("todos").filter(not(is_null(col("parent"))));let linked_todos = client.query(query, None).await?;
Multiple conditions (AND)
All predicates passed to where(...) / chained filter_* calls are AND-combined:
// done AND assigned to a projectconst doneWithProject = await db.all(app.todos.where({done: true,projectId: { isNull: false },}),);
// done AND assigned to a projectconst doneWithProject = yield* jazz.all(app.todos.where({done: true,projectId: { isNull: false },}),);
// Multiple filter calls are AND-combinedlet query = Query::from("todos").filter(eq(col("done"), lit(true))).filter(not(is_null(col("project"))));let done_with_project = client.query(query, None).await?;
Combining with ordering and limits
const recentIncomplete = await db.all(app.todos.where({ done: false }).orderBy("$createdAt", "asc").limit(50),);
const recentIncomplete = yield* jazz.all(app.todos.where({ done: false }).orderBy("$createdAt", "asc").limit(50),);
let query = Query::from("todos").filter(eq(col("done"), lit(false))).order_by("$createdAt", OrderDirection::Asc).limit(50);let recent_incomplete = client.query(query, None).await?;
Live subscriptions with WHERE
useAll and query subscriptions accept the same query builders as db.all. The subscription stays active and updates whenever any row enters or exits the filter:
export function subscribeOpenTodos(db: Db, onChange: (todos: unknown[]) => void) {return db.subscribe(app.todos.where({ done: false }), (todos) => onChange(todos));}
// A Stream of the open todos, re-emitted whenever they change.export const openTodos = Stream.unwrap(Jazz.useSync((jazz) => jazz.stream(app.todos.where({ done: false }))),);
let query = Query::from("todos").filter(eq(col("done"), lit(false)));let pending = client.subscribe(query).await?;
For reactive framework bindings (useAll in React/Vue/Solid, QuerySubscription in Svelte), see Framework Patterns.