SurrealDB
SurrealDB Docs Logo

Enter a search query

Navigation

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.

Warning

UPSERT replaces the entire record if it exists. Use update().merge() for partial updates.

Returned by: SurrealQueryable.upsert()

Source: query/upsert.ts

Type Parameters

  • T - The result type
  • I - The input type for record data
  • J - Boolean indicating if result is JSON (default: false)

Configuration Methods

.content()

Set the complete content for the record (insert or replace).

Method Syntax
upsertPromise.content(data)

Parameters

ParameterTypeDescription
data requiredValues<I>Complete record data (excluding id field).

Returns

UpsertPromise<T, I, J> - Chainable promise

Example

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 Syntax
upsertPromise.merge(data)

Parameters

ParameterTypeDescription
data requiredPartial<Values<I>>Partial data to merge.

Returns

UpsertPromise<T, I, J> - Chainable promise

Example

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 Syntax
upsertPromise.replace(data)

Parameters

ParameterTypeDescription
data requiredValues<I>Fields to replace.

Returns

UpsertPromise<T, I, J> - Chainable promise


.patch()

Apply JSON Patch operations.

Method Syntax
upsertPromise.patch(operations)

Parameters

ParameterTypeDescription
operations requiredPatchOperation[]JSON Patch operations.

Returns

UpsertPromise<T, I, J> - Chainable promise


.where()

Add a WHERE clause for conditional upsert.

Method Syntax
upsertPromise.where(condition)

Parameters

ParameterTypeDescription
condition requiredExprLikeThe condition expression (string or Expression object).

Returns

UpsertPromise<T, I, J> - Chainable promise


.output()

Specify what to return.

Method Syntax
upsertPromise.output(fields)

Parameters

ParameterTypeDescription
fields requiredOutput”NONE”, “BEFORE”, “AFTER”, “DIFF”, or field list.

Returns

UpsertPromise<T, I, J> - Chainable promise


.timeout()

Set operation timeout.

Method Syntax
upsertPromise.timeout(duration)

Returns

UpsertPromise<T, I, J> - Chainable promise


.version(), .json(), .stream()

See other query builders for these common methods.

Complete Examples

Basic Upsert

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

Upsert with Merge

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

Bulk Upsert

const users = await db.upsert(new Table('users'))
    .content(userDataArray);

Track Changes

const result = await db.upsert(new RecordId('users', 'john')) .content(userData) .output('DIFF'); if (result) { console.log('Created or updated:', result); }

Conditional Upsert

const user = await db.upsert(new RecordId('users', 'john')) .merge({ status: 'active' }) .where('verified = true');

UPSERT vs CREATE vs UPDATE

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

Use Cases

Session Management

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

Cache Pattern

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

Counter Pattern

// Increment counter or initialize const counter = await db.upsert(new RecordId('counters', 'page_views')) .merge({ count: 1, last_increment: DateTime.now() });

Chaining Pattern

const result = await db.upsert(new RecordId('users', 'john')) .content(userData) .output('AFTER') .timeout(Duration.parse('5s'));

See Also