The SDK provides utility functions and classes for building type-safe queries, creating expressions, and working with SurrealDB data efficiently.
expr - Type-safe expression builder for WHERE clauses and conditions
eq(), gt(), lt(), gte(), lte(), ne()and(), or(), not()contains(), containsAny(), containsAll()inside(), outside(), intersects()matches(), knn()surql - Tagged template for composing parameterized queries
BoundQuery - Parameterized query class with manual control
.append() - Add query segments.bind() - Add parameter bindingssurql and exprescapeIdent() - Escape table/field namesescapeKey() - Escape object keysescapeRid() - Escape record ID componentsescapeValue() - Escape valuesimport { expr, surql, eq, gte, and } from 'surrealdb'; // Build complex conditions with expr const premiumAdults = expr(and( eq('tier', 'premium'), gte('age', 18) )); const users = await db.select(new Table('users')).where(premiumAdults); // Compose queries with surql const userId = new RecordId('users', 'john'); const query = surql` SELECT *, ->purchased->products.* AS purchases FROM ${userId} `; const [result] = await db.query(query).collect();
import { surql, BoundQuery } from 'surrealdb'; // Using surql (recommended) const minAge = 18; const status = 'active'; const query = surql` SELECT * FROM users WHERE age >= ${minAge} AND status = ${status} ORDER BY created_at DESC `; const [users] = await db.query(query).collect(); // Using BoundQuery for manual control const bound = new BoundQuery( 'SELECT * FROM users WHERE status = $status', { status: 'active' } ); bound.bind('tier', 'premium'); const [results] = await db.query(bound).collect();
import { equals } from 'surrealdb'; // Deep equality for SurrealDB types const id1 = new RecordId('users', 'john'); const id2 = new RecordId('users', 'john'); if (equals(id1, id2)) { console.log('Same record'); } // Compare query results const user1 = await db.select(userId); const user2 = await db.select(userId); if (!equals(user1, user2)) { console.log('User was modified'); }
// Good: Safe parameterization const query = surql`SELECT * FROM users WHERE name = ${userName}`; // Avoid: String concatenation (SQL injection risk) const query = `SELECT * FROM users WHERE name = '${userName}'`;
// Good: Type-safe and reusable const condition = expr(and( eq('status', 'active'), gte('age', 18) )); await db.select(new Table('users')).where(condition); // Avoid: Raw strings const condition = 'status = "active" AND age >= 18';
// Good: Deep equality if (equals(recordId1, recordId2)) { // Same value } // Avoid: Reference comparison if (recordId1 === recordId2) { // Only true if same instance }