• Start

Languages

/

JavaScript

/

API Reference

/

Query builders

UpsertPromise

UpsertPromise provides chainable methods for configuring UPSERT operations (insert or replace).

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

  • T - The result type

  • I - The input type for record data

  • J - Boolean indicating if result is JSON (default: false)

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

Method Syntax
upsertPromise.content(data)

Parameter

Type

Description

dataValues<I>

Complete record data (excluding id field).

`UpsertPromise` - 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 data into the record (insert if not exists, merge if exists).

Method Syntax
upsertPromise.merge(data)

Parameter

Type

Description

dataValues<I>

Partial data to merge.

`UpsertPromise` - 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 specific fields.

Method Syntax
upsertPromise.replace(data)

Parameter

Type

Description

dataValues<I>

Fields to replace.

`UpsertPromise` - Chainable promise

Apply JSON Patch operations.

Method Syntax
upsertPromise.patch(operations)

Parameter

Type

Description

operationsValues<I>

JSON Patch operations.

`UpsertPromise` - Chainable promise

Add a WHERE clause for conditional upsert.

Method Syntax
upsertPromise.where(expr)

Parameter

Type

Description

exprExprLike

The condition expression (string or

Expression

object).

`UpsertPromise` - Chainable promise

Specify what to return.

Method Syntax
upsertPromise.output(fields)

Parameter

Type

Description

fieldsOutput"NONE"

,

"BEFORE"

,

"AFTER"

,

"DIFF"

, or field list.

`UpsertPromise` - Chainable promise

Set operation timeout.

Method Syntax
upsertPromise.timeout(duration)

`UpsertPromise` - Chainable promise

Retry the operation with exponential backoff if it fails due to a write conflict. Off by default; passing an options object (or calling with no arguments) opts the operation in.

This overrides the connection-wide default set via the retry option on ConnectOptions.

Method Syntax
upsertPromise.retry(options?)

Parameter

Type

Description

options

Partial

RetryOptions

Retry configuration. If omitted, retry is enabled with the default configuration.

`UpsertPromise` - Chainable promise

await db.upsert(new RecordId('users', 'john'))
    .merge({ visits: 1 })
    .retry();

Return result as JSON string.

Method Syntax
upsertPromise.json()

`UpsertPromise` - Promise returning JSON string

Compile the query into a BoundQuery without executing it.

Method Syntax
upsertPromise.compile()

`BoundQuery` - The compiled query

const query = db.upsert(new RecordId('users', 'john'))
    .content(userData)
    .compile();

Stream results as they arrive.

Method Syntax
upsertPromise.stream()

AsyncIterableIterator - Async iterator

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

Was this page helpful?