Skip to main content

Upsert Edges using UpsertE  

Create new edges or update existing ones with insert-or-update semantics.
UpsertE<Type>::From(node1)::To(node2)
UpsertE<Type>({properties})::From(node1)::To(node2)
UpsertE differs from AddE in that it will update an existing edge if one is found between the specified nodes, rather than always creating a new one. If no existing edge is found, it creates a new edge just like AddE.
Edge connections (::From() and ::To()) are required for UpsertE. The order of From and To is flexible.

Example 1: Basic edge upsert without properties

QUERY UpsertFriendship(id1: ID, id2: ID) =>
    person1 <- N<Person>(id1)
    person2 <- N<Person>(id2)
    UpsertE<Knows>::From(person1)::To(person2)
    RETURN "done"

QUERY CreatePerson(name: String, age: U32) =>
    person <- AddN<Person>({name: name, age: age})
    RETURN person
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

# Create two people
alice = client.query("CreatePerson", {
    "name": "Alice",
    "age": 25,
})[0]["person"]

bob = client.query("CreatePerson", {
    "name": "Bob",
    "age": 28,
})[0]["person"]

# First call creates the edge
result = client.query("UpsertFriendship", {
    "id1": alice["id"],
    "id2": bob["id"],
})

print("Created edge:", result)

# Subsequent calls update the existing edge (no duplicate created)
result = client.query("UpsertFriendship", {
    "id1": alice["id"],
    "id2": bob["id"],
})

print("Upserted edge:", result)

Example 2: Upsert edge with properties

QUERY UpsertFriendshipWithProps(id1: ID, id2: ID, since: String, strength: F32) =>
    person1 <- N<Person>(id1)
    person2 <- N<Person>(id2)
    UpsertE<Friendship>({since: since, strength: strength})::From(person1)::To(person2)
    RETURN "done"

QUERY CreatePerson(name: String, age: U32) =>
    person <- AddN<Person>({name: name, age: age})
    RETURN person
Here’s how to run the query using the SDKs or curl
from helix.client import Client

client = Client(local=True, port=6969)

alice = client.query("CreatePerson", {
    "name": "Alice",
    "age": 25,
})[0]["person"]

bob = client.query("CreatePerson", {
    "name": "Bob",
    "age": 28,
})[0]["person"]

# Create friendship with properties
result = client.query("UpsertFriendshipWithProps", {
    "id1": alice["id"],
    "id2": bob["id"],
    "since": "2024-01-15",
    "strength": 0.85,
})

print("Created friendship:", result)

# Update the friendship strength
result = client.query("UpsertFriendshipWithProps", {
    "id1": alice["id"],
    "id2": bob["id"],
    "since": "2024-01-15",
    "strength": 0.95,
})

print("Updated friendship:", result)

Example 3: Flexible From/To ordering

The ::From() and ::To() can be specified in either order.
QUERY UpsertEdgeToFrom(id1: ID, id2: ID) =>
    person1 <- N<Person>(id1)
    person2 <- N<Person>(id2)
    // To and From can be in either order
    UpsertE<Knows>::To(person2)::From(person1)
    RETURN "done"

How Upsert differs from Add

OperationBehavior
AddEAlways creates a new edge (can create duplicates)
UpsertECreates if not exists, updates if exists (no duplicates)
When updating, UpsertE merges properties: it updates specified properties while preserving any existing properties that aren’t included in the upsert.