SurrealDB
SurrealDB Docs Logo

Enter a search query

Navigation

Utilities

The SDK provides utility functions and classes for building type-safe queries, creating expressions, and working with SurrealDB data efficiently.

Query Building

  • expr - Type-safe expression builder for WHERE clauses and conditions

    • Comparison operators: eq(), gt(), lt(), gte(), lte(), ne()
    • Logical operators: and(), or(), not()
    • String/array operators: contains(), containsAny(), containsAll()
    • Geometry operators: inside(), outside(), intersects()
    • Search operators: matches(), knn()
  • surql - Tagged template for composing parameterized queries

    • Automatic value binding
    • SQL injection prevention
    • Type preservation
    • Incremental query building
  • BoundQuery - Parameterized query class with manual control

    • .append() - Add query segments
    • .bind() - Add parameter bindings
    • Used by surql and expr

Data Utilities

  • equals - Deep equality comparison for all types
    • Handles SurrealDB types (RecordId, DateTime, etc.)
    • Object and array deep comparison
    • Date and RegExp comparison
    • bigint/number normalization

Escaping & Validation

  • Escape Functions - Escape identifiers and values
    • escapeIdent() - Escape table/field names
    • escapeKey() - Escape object keys
    • escapeRid() - Escape record ID components
    • escapeValue() - Escape values

Complete Examples

Type-Safe Query Building

import { 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();

Parameterized Queries

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();

Value Comparison

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'); }

Best Practices

1. Use surql for Parameterization

// 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}'`;

2. Use expr for Complex Conditions

// 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';

3. Use equals for Deep Comparison

// Good: Deep equality if (equals(recordId1, recordId2)) { // Same value } // Avoid: Reference comparison if (recordId1 === recordId2) { // Only true if same instance }

See Also