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
Type Parameters
T - The result type (edge record type)J - Boolean indicating if result is JSON (default: false)
Configuration Methods
.unique()
Enforce a unique relationship constraint (only one edge between the same nodes).
Method Syntax
relatePromise.unique()
Returns
RelatePromise<T, J> - Chainable promise
Example
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1')
).unique();
.output()
Specify what to return from the operation.
Method Syntax
relatePromise.output(fields)
Parameters
| Parameter | Type | Description |
|---|
fields required | Output | ”NONE”, “AFTER”, or specific field list. |
Returns
RelatePromise<T, J> - Chainable promise
Example
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('follows'),
new RecordId('users', 'jane')
).output('id', 'in', 'out', 'created_at');
.timeout()
Set a timeout for the operation.
Method Syntax
relatePromise.timeout(duration)
Parameters
| Parameter | Type | Description |
|---|
duration required | Duration | Maximum time to wait. |
Returns
RelatePromise<T, J> - Chainable promise
.version()
Create the relationship at a specific version.
Method Syntax
relatePromise.version(timestamp)
Parameters
| Parameter | Type | Description |
|---|
timestamp required | DateTime | The version timestamp. |
Returns
RelatePromise<T, J> - Chainable promise
.json()
Return result as JSON string.
Method Syntax
relatePromise.json()
Returns
RelatePromise<T, true> - Promise returning JSON string
.stream()
Stream results as relationships are created.
Method Syntax
relatePromise.stream()
Returns
AsyncIterableIterator - Async iterator
Complete Examples
Basic Relationship
import { Surreal, RecordId, Table, DateTime } from 'surrealdb';
const db = new Surreal();
await db.connect('ws://localhost:8000');
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);
console.log('To:', edge.out);
Multiple Relationships
const edges = await db.relate(
[new RecordId('users', 'john'), new RecordId('users', 'jane')],
new Table('follows'),
[new RecordId('users', 'alice'), new RecordId('users', 'bob')]
);
Unique Relationships
const edge = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1'),
{ timestamp: DateTime.now() }
).unique();
const duplicate = await db.relate(
new RecordId('users', 'john'),
new Table('likes'),
new RecordId('posts', '1')
).unique();
Relationship with Data
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']
}
);
Specific Edge ID
const edge = await db.relate(
new RecordId('users', 'john'),
new RecordId('likes', 'specific-edge-id'),
new RecordId('posts', '1'),
{ strength: 10 }
);
Fan-out Relationships
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`);
Streaming Bulk Relationships
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}`);
}
Bidirectional Relationships
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'
}
);
Temporal Relationships
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'
}
);
Weighted Graph
const edge = await db.relate(
new RecordId('cities', 'new-york'),
new Table('connected_to'),
new RecordId('cities', 'boston'),
{
distance: 215,
travel_time: Duration.parse('4h'),
cost: 50
}
);
Delete and Recreate Pattern
const userId = new RecordId('users', 'john');
const postId = new RecordId('posts', '1');
await db.query(
surql`DELETE FROM likes WHERE in = ${userId} AND out = ${postId}`
).collect();
const edge = await db.relate(
userId,
new Table('likes'),
postId,
{ created_at: DateTime.now() }
);
Graph Traversal Example
await db.relate(
new RecordId('users', 'john'),
new Table('follows'),
new RecordId('users', 'jane')
);
const followers = await db.query(
surql`SELECT <-follows<-users.* AS followers FROM users:jane`
).collect();
console.log('Jane has followers:', followers);
Best Practices
1. Use Unique for One-to-One
await db.relate(from, new Table('likes'), to).unique();
await db.relate(from, new Table('likes'), to);
await db.relate(from, edge, to, {
created_at: DateTime.now(),
source: 'web-app'
});
await db.relate(from, edge, to);
3. Use Specific Edge IDs for Updates
const edgeId = new RecordId('likes', Uuid.v7());
await db.relate(from, edgeId, to, metadata);
await db.update(edgeId).merge({ updated_at: DateTime.now() });
See Also