The UPSERT statement allows you to update existing nodes and edges in the graph. If no existing date with the same _id is found, it inserts a new one instead.
Unlike INSERT OVERWRITE which replaces the whole entity, UPSERT preserves existing properties and only updates or adds the properties supplied in the statement.
UPSERT is useful in import or sync workflows where the same script may be re-run: existing rows get refreshed properties without manual existence checks, and unaffected fields stay intact.
If a node with the specified _id does not exist, UPSERT inserts a new node:
GQLUPSERT (:User {_id: "U2", name: "Jumpy88", level: 1})
If a node with _id as U2 already exists, the listed properties (name, level) are written over the existing values. Properties of the existing node that are not in the write are kept as-is.
GQLUPSERT (:User {_id: "U2", level: 2})
After this statement, the existing name of U2 remains "Jumpy88", and level is updated to 2.
If _id is omitted, a new node is inserted with a system-generated _id:
GQLUPSERT (:User {name: "Jumpy88"})
Upserting edges keys on the edge's _id and therefore requires EDGE_ID to be enabled on the graph. On a graph with EDGE_ID disabled, UPSERT on an edge is rejected with an error. See Graphs with Edge ID.
When EDGE_ID is enabled, an existing edge is updated if _id is included in the edge property specification and an edge with that _id exists:
GQLMATCH (u:User {name: 'claire'}), (c:Club {_id: 'C1'}) UPSERT (u)-[:Joins {_id: 'E1', fee: 1200}]->(c)
If an edge with _id as E1 already exists, the listed properties (fee) are written over the existing values. Other properties of the edge are kept as-is.
If _id is omitted, a new edge is always inserted with an auto-generated UUID v4 _id:
GQLMATCH (u:User {name: 'claire'}), (c:Club {_id: 'C1'}) UPSERT (u)-[:Joins {fee: 1500}]->(c)
NOTEThe endpoint nodes and the edge label must still resolve correctly.
UPSERTcannot be used to move an existing edge to different endpoints or change its label.