Skip to main content

Upsert Nodes using UpsertN  

Create new nodes or update existing ones with insert-or-update semantics.
UpsertN<Type>
UpsertN<Type>()
UpsertN<Type>({properties})
UpsertN differs from AddN in that it will update an existing node if one is found in the traversal context, rather than always creating a new one. If no existing node is found, it creates a new node just like AddN.
When using the SDKs or curling the endpoint, the query name must match what is defined in the queries.hx file exactly.

Example 1: Basic node upsert with properties

QUERY UpsertPerson(name: String, age: U32) =>
    person <- UpsertN<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)

# First call creates a new person
person = client.query("UpsertPerson", {
    "name": "Alice",
    "age": 25,
})

print("Created person:", person)

# Subsequent calls with same data update the existing person
updated = client.query("UpsertPerson", {
    "name": "Alice",
    "age": 26,
})

print("Updated person:", updated)

Example 2: Upsert an empty node

QUERY UpsertPersonEmpty() =>
    person <- UpsertN<Person>()
    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)
print(client.query("UpsertPersonEmpty"))

Example 3: Upsert with traversal context

When used after a traversal that returns existing nodes, UpsertN will update those nodes rather than creating new ones.
QUERY UpdateOrCreatePerson(name: String, new_age: U32) =>
    // Find existing person or create new one with the given properties
    existing <- N<Person>::WHERE(_::{name}::EQ(name))
    person <- existing::UpsertN<Person>({name: name, age: new_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)

# If "Alice" exists, updates her age; otherwise creates a new person
result = client.query("UpdateOrCreatePerson", {
    "name": "Alice",
    "new_age": 30,
})

print("Upserted person:", result)

How Upsert differs from Add and Update

OperationBehavior
AddNAlways creates a new node
UPDATEOnly modifies existing nodes (fails if node doesn’t exist)
UpsertNCreates if not exists, updates if exists
When updating, UpsertN merges properties: it updates specified properties while preserving any existing properties that aren’t included in the upsert.