UpsertPromise<T, I, J>The UpsertPromise class provides a chainable interface for configuring UPSERT operations (insert if not exists, replace if exists). It extends Promise, allowing you to await it directly or chain configuration methods.
WarningUPSERT replaces the entire record if it exists. Use
update().merge()for partial updates.
Returned by: SurrealQueryable.upsert()
Source: query/upsert.ts
T - The result typeI - The input type for record dataJ - Boolean indicating if result is JSON (default: false).content()Set the complete content for the record (insert or replace).
Method SyntaxupsertPromise.content(data)
| Parameter | Type | Description |
|---|---|---|
data required | Values<I> | Complete record data (excluding id field). |
UpsertPromise<T, I, J> - Chainable promise
const user = await db.upsert(new RecordId('users', 'john')) .content({ name: 'John Doe', email: 'john@example.com', age: 30 }); // Inserts if not exists, replaces entirely if exists
.merge()Merge data into the record (insert if not exists, merge if exists).
Method SyntaxupsertPromise.merge(data)
| Parameter | Type | Description |
|---|---|---|
data required | Partial<Values<I>> | Partial data to merge. |
UpsertPromise<T, I, J> - Chainable promise
const user = await db.upsert(new RecordId('users', 'john')) .merge({ name: 'John Doe', last_login: DateTime.now() }); // If exists: merges fields; if not: creates with these fields
.replace()Replace specific fields.
Method SyntaxupsertPromise.replace(data)
| Parameter | Type | Description |
|---|---|---|
data required | Values<I> | Fields to replace. |
UpsertPromise<T, I, J> - Chainable promise
.patch()Apply JSON Patch operations.
Method SyntaxupsertPromise.patch(operations)
| Parameter | Type | Description |
|---|---|---|
operations required | PatchOperation[] | JSON Patch operations. |
UpsertPromise<T, I, J> - Chainable promise
.where()Add a WHERE clause for conditional upsert.
Method SyntaxupsertPromise.where(condition)
| Parameter | Type | Description |
|---|---|---|
condition required | ExprLike | The condition expression (string or Expression object). |
UpsertPromise<T, I, J> - Chainable promise
.output()Specify what to return.
Method SyntaxupsertPromise.output(fields)
| Parameter | Type | Description |
|---|---|---|
fields required | Output | ”NONE”, “BEFORE”, “AFTER”, “DIFF”, or field list. |
UpsertPromise<T, I, J> - Chainable promise
.timeout()Set operation timeout.
Method SyntaxupsertPromise.timeout(duration)
UpsertPromise<T, I, J> - Chainable promise
.version(), .json(), .stream()See other query builders for these common methods.
import { Surreal, RecordId } from 'surrealdb'; const db = new Surreal(); await db.connect('ws://localhost:8000'); // Upsert: insert if not exists, replace if exists const user = await db.upsert(new RecordId('users', 'john')) .content({ name: 'John Doe', email: 'john@example.com', role: 'user' });
// Safer: merge instead of replace const user = await db.upsert(new RecordId('users', 'john')) .merge({ last_login: DateTime.now(), login_count: 1 }); // If user exists: only updates these fields // If not: creates user with these fields
const users = await db.upsert(new Table('users')) .content(userDataArray);
const result = await db.upsert(new RecordId('users', 'john')) .content(userData) .output('DIFF'); if (result) { console.log('Created or updated:', result); }
const user = await db.upsert(new RecordId('users', 'john')) .merge({ status: 'active' }) .where('verified = true');
// CREATE: Fails if record exists try { await db.create(recordId).content(data); } catch (error) { // Error if exists } // UPDATE: Fails if record doesn't exist try { await db.update(recordId).merge(data); } catch (error) { // Error if not found } // UPSERT: Works in both cases await db.upsert(recordId).content(data); // Always succeeds
// Update session or create new one async function updateSession(sessionId: string, data: SessionData) { return db.upsert(new RecordId('sessions', sessionId)) .merge({ ...data, last_activity: DateTime.now() }); }
// Write-through cache async function cacheSet(key: string, value: unknown) { return db.upsert(new RecordId('cache', key)) .content({ value, expires_at: DateTime.now().plus(Duration.parse('1h')) }); }
// Increment counter or initialize const counter = await db.upsert(new RecordId('counters', 'page_views')) .merge({ count: 1, last_increment: DateTime.now() });
const result = await db.upsert(new RecordId('users', 'john')) .content(userData) .output('AFTER') .timeout(Duration.parse('5s'));