RelatePromise<T, J>

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

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 specific ID to update later
const edgeId = new RecordId('likes', Uuid.v7());
await db.relate(from, edgeId, to, metadata);

// Later: easy to update
await db.update(edgeId).merge({ updated_at: DateTime.now() });

Was this page helpful?