SurrealDB
SurrealDB Docs Logo

Enter a search query

Navigation

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

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

.output()

Specify what to return from the operation.

Method Syntax
relatePromise.output(fields)

Parameters

ParameterTypeDescription
fields requiredOutput”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

ParameterTypeDescription
duration requiredDurationMaximum time to wait.

Returns

RelatePromise<T, J> - Chainable promise


.version()

Create the relationship at a specific version.

Method Syntax
relatePromise.version(timestamp)

Parameters

ParameterTypeDescription
timestamp requiredDateTimeThe 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'); // 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

Multiple Relationships

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

Unique Relationships

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

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

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

Fan-out Relationships

// 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`);

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

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

Relationship Metadata

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

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

Weighted Graph

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

Delete and Recreate Pattern

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

Graph Traversal Example

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

Best Practices

1. Use Unique for One-to-One

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

2. Include Metadata

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

3. Use Specific Edge IDs for Updates

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

See Also