The RecordId class provides type-safe record identifiers in SurrealDB. Each record ID consists of a table name and an ID value, represented as table:id in SurrealQL.
Import:
import { RecordId } from 'surrealdb' ; Source: value/record-id.ts
Type Parameters Tb extends string - The table name (string literal type for type safety)
Id - The ID value type (string, number, object, etc.)
Constructor new RecordId(table, id)Create a new record identifier.
Parameters Parameter Type Description table Tb | Table<Tb>The table name, either as a string or a Table instance. id IdThe record ID value (string, number, object, array, or RecordId).
Examples // String IDs const user = new RecordId ( 'users' , 'john' ) ; const post = new RecordId ( 'posts' , '123' ) ; // Numeric IDs const product = new RecordId ( 'products' , 42 ) ; // Complex/structured IDs const metric = new RecordId ( 'metrics' , { service : 'api' , timestamp : 1234567890 } ) ; // Array IDs const compound = new RecordId ( 'items' , [ 'type-a' , 123 ] ) ; // Nested RecordId const nested = new RecordId ( 'links' , new RecordId ( 'users' , 'alice' ) ) ; // Type-safe with generics const typedUser = new RecordId < 'users' , string > ( 'users' , 'john' ) ; Properties tableThe table name component, returned as a Table instance.
Type: Table<Tb>
const userId = new RecordId ( 'users' , 'john' ) ; console . log ( userId . table ) ; // Table { name: 'users' } console . log ( userId . table . name ) ; // 'users'
idThe ID value component.
Type: Id
const userId = new RecordId ( 'users' , 'john' ) ; console . log ( userId . id ) ; // 'john' const productId = new RecordId ( 'products' , 42 ) ; console . log ( productId . id ) ; // 42 Instance Methods .toString()Convert the record ID to its string representation.
Returns string - String representation in format table:id
Examples const userId = new RecordId ( 'users' , 'john' ) ; console . log ( userId . toString ( ) ) ; // 'users:john' const productId = new RecordId ( 'products' , 42 ) ; console . log ( productId . toString ( ) ) ; // 'products:42' const complex = new RecordId ( 'items' , { type : 'widget' , id : 5 } ) ; console . log ( complex . toString ( ) ) ; // 'items:{ type: "widget", id: 5 }'
.toJSON()Serialize the record ID for JSON.
Returns string - JSON-safe string representation
const userId = new RecordId ( 'users' , 'john' ) ; console . log ( JSON . stringify ( userId ) ) ; // '"users:john"'
.equals(other)Check if two record IDs are equal.
Parameters Parameter Type Description other unknownValue to compare.
Returns boolean - True if equal
const a = new RecordId ( 'users' , 'john' ) ; const b = new RecordId ( 'users' , 'john' ) ; const c = new RecordId ( 'users' , 'jane' ) ; console . log ( a . equals ( b ) ) ; // true console . log ( a . equals ( c ) ) ; // false Complete Examples Basic Usage import { Surreal , RecordId } from 'surrealdb' ; const db = new Surreal ( ) ; await db . connect ( 'ws://localhost:8000' ) ; // Create record with specific ID const user = await db . create ( new RecordId ( 'users' , 'john' ) ) . content ( { name : 'John Doe' , email : 'john@example.com' } ) ; // Select by record ID const retrieved = await db . select ( new RecordId ( 'users' , 'john' ) ) ; // Update by record ID await db . update ( new RecordId ( 'users' , 'john' ) ) . merge ( { status : 'active' } ) ; // Delete by record ID await db . delete ( new RecordId ( 'users' , 'john' ) ) ; Type-Safe Record IDs interface User { id : RecordId < 'users' , string > ; name : string ; email : string ; } // TypeScript enforces correct table name const userId : RecordId < 'users' , string > = new RecordId ( 'users' , 'alice' ) ; // This would be a type error: // const wrong: RecordId<'posts', string> = new RecordId('users', 'alice'); const user = await db . select < User > ( userId ) ; Complex ID Structures // Time-series data with structured IDs const metricId = new RecordId ( 'metrics' , { service : 'api' , host : 'server-01' , timestamp : 1234567890 } ) ; await db . create ( metricId ) . content ( { cpu : 45.2 , memory : 78.1 } ) ; // Compound keys const sessionId = new RecordId ( 'sessions' , { userId : 'john' , deviceId : 'device-123' } ) ; Parsing from Strings Use StringRecordId to pass a record ID string directly without parsing it into table and ID components. The string is sent as-is to SurrealDB.
import { StringRecordId } from 'surrealdb' ; // Use a record ID string directly const userInput = 'users:john' ; const userId = new StringRecordId ( userInput ) ; const user = await db . select ( userId ) ; // Use in queries const recordId = new StringRecordId ( 'users:alice' ) ; const result = await db . select ( recordId ) ; Working with Relations // Create relationship using record IDs const from = new RecordId ( 'users' , 'john' ) ; const to = new RecordId ( 'posts' , '123' ) ; const edge = await db . relate ( from , new Table ( 'likes' ) , to , { timestamp : DateTime . now ( ) } ) ; console . log ( 'Edge from:' , edge . in ) ; // RecordId('users', 'john') console . log ( 'Edge to:' , edge . out ) ; // RecordId('posts', '123') UUID-based Record IDs import { Uuid } from 'surrealdb' ; // Generate time-ordered IDs const userId = new RecordId ( 'users' , Uuid . v7 ( ) ) ; // Generate random IDs const sessionId = new RecordId ( 'sessions' , Uuid . v4 ( ) ) ; await db . create ( userId ) . content ( { name : 'Alice' , created : DateTime . now ( ) } ) ; Validation // Table names are validated automatically try { const invalid = new RecordId ( 'invalid-table!' , 'id' ) ; } catch ( error ) { console . error ( 'Invalid table name' ) ; } RecordIdRange The RecordIdRange class represents a range of record IDs for querying multiple records.
Bounds are specified using the BoundIncluded and BoundExcluded classes, or undefined for unbounded:
new BoundIncluded(value) — inclusive bound (>= or <=)
new BoundExcluded(value) — exclusive bound (> or <)
undefined — unbounded (no limit)
Constructor new RecordIdRange ( table , begin , end ) Parameters Parameter Type Description table Tb | Table<Tb>The table name, either as a string or a Table instance. begin Bound<Id>Start of the range. Use BoundIncluded, BoundExcluded, or undefined. end Bound<Id>End of the range. Use BoundIncluded, BoundExcluded, or undefined.
Examples import { RecordIdRange , BoundIncluded , BoundExcluded } from 'surrealdb' ; // Select range of users from 'a' (inclusive) to 'f' (exclusive) const range = new RecordIdRange ( 'users' , new BoundIncluded ( 'a' ) , new BoundExcluded ( 'f' ) , ) ; const users = await db . select ( range ) ; // Numeric range: 1 (inclusive) to 100 (inclusive) const numRange = new RecordIdRange ( 'items' , new BoundIncluded ( 1 ) , new BoundIncluded ( 100 ) , ) ; const items = await db . select ( numRange ) ; // Unbounded start, exclusive end const upToF = new RecordIdRange ( 'users' , undefined , new BoundExcluded ( 'f' ) , ) ; // Inclusive start, unbounded end const fromA = new RecordIdRange ( 'users' , new BoundIncluded ( 'a' ) , undefined , ) ; // Delete range await db . delete ( new RecordIdRange ( 'logs' , new BoundIncluded ( '2024-01-01' ) , new BoundExcluded ( '2024-02-01' ) , ) ) ; Best Practices 1. Use Type Parameters // Good: Type-safe type UserId = RecordId < 'users' , string > ; const userId : UserId = new RecordId ( 'users' , 'john' ) ; // Better: Enforce at compile time function getUser ( id : RecordId < 'users' , string > ) { return db . select ( id ) ; } 2. Prefer RecordId Over Strings // Good: Type-safe with validation const user = await db . select ( new RecordId ( 'users' , 'john' ) ) ; // Avoid: String-based (no validation) const user = await db . query ( 'SELECT * FROM users:john' ) . collect ( ) ; 3. Use Structured IDs for Complex Keys // Good: Structured composite key const id = new RecordId ( 'events' , { userId : 'john' , timestamp : Date . now ( ) } ) ; // Avoid: String concatenation const id = new RecordId ( 'events' , `john- ${ Date . now ( ) } ` ) ; 4. Handle Construction Errors // Good: Safe construction try { const id = new RecordId ( tableName , idValue ) ; const record = await db . select ( id ) ; } catch ( error ) { console . error ( 'Invalid record ID format' ) ; } See Also