The role of elementIds and key properties
Neo4j internally identifies nodes and relationships by their elementId. Although these internal identifiers are always part of the generated change events, they are not safe to track data out of the scope of a single transaction. You should thus define logical/business keys to your graph entities in the form of node key constraints and relationships key constraints. Properties with node and relationship key constraints are always included in change events as top-level objects.
If key constraints are defined on graph entities, all of the participating property values are captured as event.keys
field on node changes and relationship changes.
Furthermore, a relationship change also includes the corresponding participating key property values for the relationship’s start
and end
nodes.
If the node or relationship key constraints are added after a change event is captured, the previously captured change events are not updated with key information retroactively. The key properties are captured from the point the corresponding constraints are created. |
Node keys
Assume the following constraints are in place for Person
and Employee
labels.
Person
labelCREATE CONSTRAINT person_names_key IF NOT EXISTS FOR (n:Person) REQUIRE (n.firstName, n.lastName) IS NODE KEY;
CREATE CONSTRAINT person_ssn_key IF NOT EXISTS FOR (n:Person) REQUIRE (n.ssn) IS NODE KEY;
Employee
labelCREATE CONSTRAINT employee_key IF NOT EXISTS FOR (n:Employee) REQUIRE (n.id) IS NODE KEY
Whenever a change happens on a node with Person
label with firstName
, lastName
and ssn
properties set as john
, doe
and X123456
respectively, the change event includes the following key information.
{
//...
"event": {
"keys": {
"Person": [
{
"firstName": "john",
"lastName": "doe"
},
{
"ssn": "X123456"
}
]
}
}
//...
}
Likewise, whenever a change happens on a node with Employee
label with id
property set as 1001
, the change event includes the following key information.
{
//...
"event": {
"keys": {
"Employee": [
{
"id": 1001
}
]
}
}
//...
}
If, on the other hand, the changed node has both Person
and Employee
labels with firstName
, lastName
, ssn
and id
properties set as john
, doe
, Y654321
and 1001
respectively, the change event includes the following key information.
{
//...
"event": {
"keys": {
"Person": [
{
"firstName": "john",
"lastName": "doe"
},
{
"ssn": "Y654321"
}
],
"Employee": [
{
"id": 1001
}
]
}
}
//...
}
For a full description of change record schema, see Format of change events.
Although the preferred way of specifying node key properties is creating a node key constraint, the same can be achieved using both unique node property and node property existence constraints on the same set of properties.
|
For details about constraints and syntax of related commands, see Cypher Manual → Constraints.
Relationship keys
Assume the following constraints are in place for MARRIED_TO
relationship type.
MARRIED_TO
typeCREATE CONSTRAINT married_to_register_key IF NOT EXISTS FOR ()-[r:MARRIED_TO]-() REQUIRE (r.registerId) IS RELATIONSHIP KEY;
CREATE CONSTRAINT married_to_official_key IF NOT EXISTS FOR ()-[r:MARRIED_TO]-() REQUIRE (r.official) IS RELATIONSHIP KEY;
Whenever a change happens on a relationship of type MARRIED_TO
with registerId
and official
properties set as 1125
and Alice Roberts
respectively, the change event includes the following key information.
{
//...
"event": {
"keys": [
{
"registerId": 1125
},
{
"official": "Alice Roberts"
}
]
}
//...
}
If the relationship’s start and end nodes correspond to nodes with node key constraint, those property values are also included in the change event.
{
//...
"event": {
"start": {
"elementId": "<element-id>",
"labels": ["Person"],
"keys": {
"Person": [
{
"firstName": "john",
"lastName": "doe"
}
]
}
},
"end": {
"elementId": "<element-id>",
"labels": ["Person"],
"keys": {
"Person": [
{
"firstName": "mary",
"lastName": "doe"
}
]
}
},
"keys": [
{
"registerId": 1125
},
{
"official": "Alice Roberts"
}
]
}
//...
}
For a full description of change record schema, see Format of change events.
Although the preferred way of specifying relationship key properties is creating relationship key constraint, the same can be achieved using both unique relationship property and relationship property existence constraints on the same set of properties.
|
For details about constraints and syntax of related commands, see Cypher Manual → Constraints.