The Query class provides a configurable interface for executing raw SurrealQL statements with support for streaming, batch processing, and response handling. It extends Promise, allowing you to await it directly or use specialized methods.
// Simple query constresult=awaitdb.query('SELECT * FROM users').collect(); console.log(result[0]);// Array of users
// With await (same as .collect()) constresult=awaitdb.query('SELECT * FROM users');
Parameterized Queries
// Using bindings object constresult=awaitdb.query( 'SELECT * FROM users WHERE age > $age AND status = $status', {age:18,status:'active'} ).collect();
// Using surql template import{surql}from'surrealdb';
constminAge=18; constresult=awaitdb.query( surql`SELECT * FROM users WHERE age > ${minAge}` ).collect();
Multiple Statements
const[users,posts,comments]=awaitdb.query<[User[],Post[],Comment[]]>(` SELECT * FROM users; SELECT * FROM posts WHERE published = true; SELECT * FROM comments WHERE approved = true; `).collect();
forawait(constframeofquery.stream()){ if(frame.type==='value'){ // Process each chunk as it arrives awaitprocessChunk(frame.value); }elseif(frame.type==='error'){ console.error('Error:',frame.error); break; } }
Error Handling with Responses
constresponses=awaitdb.query(` CREATE users:john SET name = 'John'; CREATE users:john SET name = 'Duplicate'; SELECT * FROM users:john; `).responses();
constresult=awaitdb.query( surql` LET $active_users = SELECT * FROM users WHERE status = ${status}; LET $adult_users = SELECT * FROM users WHERE age >= ${minAge}; RETURN { active: $active_users, adults: $adult_users, both: SELECT * FROM $active_users WHERE age >= ${minAge} }; ` ).collect();
Data Migration
// Batch update with query constmigration=awaitdb.query(` -- Add new field to all users UPDATE users SET new_field = 'default_value'; -- Migrate data format UPDATE users SET profile = { bio: bio, avatar: avatar_url }; -- Remove old fields UPDATE users UNSET bio, avatar_url; `).collect();
console.log('Migration complete');
Streaming with Progress
lettotalRecords=0; letqueriesCompleted=0;
forawait(constframeofdb.query('SELECT * FROM users; SELECT * FROM posts;').stream()){ if(frame.type==='value'){ totalRecords+=frame.value.length; console.log(`Received ${frame.value.length} records`); }elseif(frame.type==='done'){ queriesCompleted++; console.log(`Query ${frame.query} completed`); } }
console.log(`Total: ${totalRecords} records from ${queriesCompleted} queries`);
Best Practices
1. Use Parameterization
// Good: Parameterized constresult=awaitdb.query( 'SELECT * FROM users WHERE name = $name', {name:userName} ).collect();
// Better: Use surql template constresult=awaitdb.query( surql`SELECT * FROM users WHERE name = ${userName}` ).collect();
// Avoid: String concatenation (SQL injection risk) constresult=awaitdb.query( `SELECT * FROM users WHERE name = '${userName}'` ).collect();