• Start

Languages

/

JavaScript

/

API Reference

/

Query Builders

RelatePromise

RelatePromise provides chainable methods for configuring RELATE operations for graph relationships.

The RelatePromise class provides a chainable interface for configuring RELATE operations to create graph relationships (edges) between records. It extends Promise, allowing you to await it directly or chain configuration methods.

Returned by: SurrealQueryable.relate()

Source: query/relate.ts

  • T - The result type (edge record type)

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

Enforce a unique relationship constraint (only one edge between the same nodes).

Method Syntax

relatePromise.unique()

RelatePromise<T, J> - Chainable promise

// Only allow one 'likes' edge between user and post
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1')
).unique();
// If edge already exists, this won't create a duplicate

Specify what to return from the operation.

Method Syntax

relatePromise.output(fields)
ParameterTypeDescription
fields Output"NONE", "AFTER", or specific field list.

RelatePromise<T, J> - Chainable promise

const edge = await db.relate(
new RecordId('users', 'john'),
new Table('follows'),
new RecordId('users', 'jane')
).output('id', 'in', 'out', 'created_at');

Set a timeout for the operation.

Method Syntax

relatePromise.timeout(duration)
ParameterTypeDescription
duration DurationMaximum time to wait.

RelatePromise<T, J> - Chainable promise

Create the relationship at a specific version.

Method Syntax

relatePromise.version(timestamp)
ParameterTypeDescription
timestamp DateTimeThe version timestamp.

RelatePromise<T, J> - Chainable promise

Return result as JSON string.

Method Syntax

relatePromise.json()

RelatePromise<T, true> - Promise returning JSON string

Compile the query into a BoundQuery.

Method Syntax

relatePromise.compile()

BoundQuery<[T]> - The compiled query

Stream results as relationships are created.

Method Syntax

relatePromise.stream()

AsyncIterableIterator - Async iterator

import { Surreal, RecordId, Table, DateTime } from 'surrealdb';

const db = new Surreal();
await db.connect('ws://localhost:8000');

// Create a single relationship
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1'),
{ created_at: DateTime.now() }
);

console.log('Edge created:', edge.id);
console.log('From:', edge.in); // users:john
console.log('To:', edge.out); // posts:1
// Create multiple edges at once
const edges = await db.relate(
[new RecordId('users', 'john'), new RecordId('users', 'jane')],
new Table('follows'),
[new RecordId('users', 'alice'), new RecordId('users', 'bob')]
);

// Creates 4 edges:
// john->follows->alice
// john->follows->bob
// jane->follows->alice
// jane->follows->bob
// Prevent duplicate 'likes'
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1'),
{ timestamp: DateTime.now() }
).unique();

// Second call won't create duplicate
const duplicate = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1')
).unique();
// Returns existing edge
const friendship = await db.relate(
new RecordId('users', 'john'),
new Table('friends'),
new RecordId('users', 'jane'),
{
since: DateTime.parse('2024-01-15'),
strength: 0.8,
mutual: true,
tags: ['colleague', 'neighbor']
}
);
// Use specific ID for the edge
const edge = await db.relate(
new RecordId('users', 'john'),
new RecordId('likes', 'specific-edge-id'),
new RecordId('posts', '1'),
{ strength: 10 }
);
// One user follows many
const edges = await db.relate(
new RecordId('users', 'john'),
new Table('follows'),
[
new RecordId('users', 'alice'),
new RecordId('users', 'bob'),
new RecordId('users', 'carol')
]
);

console.log(`Created ${edges.length} follow edges`);
const users = await db.select(new Table('users'));
const popularPost = new RecordId('posts', 'viral-post');

const edges = db.relate(
users.map(u => u.id),
new Table('viewed'),
popularPost,
{ viewed_at: DateTime.now() }
);

for await (const edge of edges.stream()) {
console.log(`Created view edge: ${edge.id}`);
}
// Create friendship in both directions
await db.relate(
new RecordId('users', 'john'),
new Table('friends'),
new RecordId('users', 'jane')
);

await db.relate(
new RecordId('users', 'jane'),
new Table('friends'),
new RecordId('users', 'john')
);
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('rated'),
new RecordId('movies', 'inception'),
{
rating: 5,
review: 'Amazing movie!',
watched_at: DateTime.parse('2024-01-15'),
platform: 'Netflix'
}
);
// Track when relationship was created
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('employed_at'),
new RecordId('companies', 'acme'),
{
started_at: DateTime.parse('2024-01-01'),
position: 'Developer',
department: 'Engineering'
}
);
// Create weighted edges for graph algorithms
const edge = await db.relate(
new RecordId('cities', 'new-york'),
new Table('connected_to'),
new RecordId('cities', 'boston'),
{
distance: 215, // miles
travel_time: Duration.parse('4h'),
cost: 50
}
);
// Remove existing relationship and create new one
const userId = new RecordId('users', 'john');
const postId = new RecordId('posts', '1');

// Delete existing edge
await db.query(
surql`DELETE FROM likes WHERE in = ${userId} AND out = ${postId}`
).collect();

// Create new edge with updated data
const edge = await db.relate(
userId,
new Table('likes'),
postId,
{ created_at: DateTime.now() }
);
// Create relationships
await db.relate(
new RecordId('users', 'john'),
new Table('follows'),
new RecordId('users', 'jane')
);

// Query traversal
const followers = await db.query(
surql`SELECT <-follows<-users.* AS followers FROM users:jane`
).collect();

console.log('Jane has followers:', followers);
// Good: Prevent duplicate likes
await db.relate(from, new Table('likes'), to).unique();

// Avoid: Allowing duplicates
await db.relate(from, new Table('likes'), to);
// May create multiple edges
// Good: Track when relationship was created
await db.relate(from, edge, to, {
created_at: DateTime.now(),
source: 'web-app'
});

// Basic: No metadata
await db.relate(from, edge, to);
// Good: use a specific ID so you can update the edge later
const edgeId = new RecordId('likes', [from.toString(), to.toString()]);
await db.relate(from, edgeId, to, metadata);

// Later: update by record ID
await db.update(edgeId).merge({ updated_at: DateTime.now() });

As of SurrealDB 3.1.5, when the edge ID already exists, INSERT RELATION returns an error unless you use ON DUPLICATE KEY UPDATE. See Explicit edge record IDs for more details.

Was this page helpful?