Hi,
I have the following triggers defined in a Neo4j 5.x database. The idea is to set a created
property on every node/relationship, and create/update an updated
property on every node/relationship:
CALL apoc.trigger.install('mydb', 'setNodeCreated', 'UNWIND $createdNodes AS n SET n.created = coalesce(n.created, datetime()), n.updated = coalesce(n.updated, datetime())', { phase: 'before' });
CALL apoc.trigger.install('mydb', 'setNodeUpdated', '
UNWIND keys($assignedNodeProperties) AS key WITH key UNWIND apoc.trigger.propertiesByKey($assignedNodeProperties, key) AS prop WITH prop.node AS n WHERE n IS NOT NULL AND NOT n IN $createdNodes SET n.updated = datetime()
WITH n
UNWIND keys($removedNodeProperties) AS key WITH key UNWIND apoc.trigger.propertiesByKey($removedNodeProperties, key) AS prop WITH prop.node AS n WHERE n IS NOT NULL AND NOT n IN $createdNodes SET n.updated = datetime()
WITH n
UNWIND keys($assignedLabels) AS label WITH label UNWIND apoc.trigger.nodesByLabel($assignedLabels, label) AS n WITH n WHERE n IS NOT NULL AND NOT n IN $createdNodes SET n.updated = datetime()
WITH n
UNWIND keys($removedLabels) AS label WITH label UNWIND apoc.trigger.nodesByLabel($removedLabels, label) AS n WITH n WHERE n IS NOT NULL AND NOT n IN $createdNodes SET n.updated = datetime()',
{ phase: 'before' });
CALL apoc.trigger.install('mydb', 'setRelCreated', 'UNWIND $createdRelationships AS r WITH r WHERE r IS NOT NULL SET r.created = coalesce(r.created, datetime()), r.updated = coalesce(r.updated, datetime())', { phase: 'before' });
CALL apoc.trigger.install('mydb', 'setRelUpdated', '
UNWIND keys($assignedRelationshipProperties) AS key WITH key UNWIND apoc.trigger.propertiesByKey($assignedRelationshipProperties, key) AS prop WITH prop.relationship AS r WHERE r IS NOT NULL AND NOT r IN $createdRelationships SET r.updated = datetime()
WITH r
UNWIND keys($removedRelationshipProperties) AS key WITH key UNWIND apoc.trigger.propertiesByKey($removedRelationshipProperties, key) AS prop WITH prop.relationship AS r WHERE r IS NOT NULL AND NOT r IN $createdRelationships SET r.updated = datetime()',
{ phase: 'before' });
The triggers themselves work, generally. However, there is an issue when a newly created node already has an updated
property. I'm migrating some data from a non-Neo4j database, and in the instance where an incoming record already has an updated
value, I want to retain that value, versus always setting node.updated to the current date/time. This requirement is only in the case of a node being newly created; any updates to the node should result in node.updated
getting set to the current date/time.
It seems as though the setNodeCreated
trigger is running, and retaining the updated
value as desired. But then the setNodeUpdated
trigger runs, which immediately changes the node.updated value. As you can see, I tried adding a where clause in setNodeUpdated
to not operate on nodes in the $createdNodes
list, but it doesn't seem to work. The updated
property is always set to the current date/time.
Any thoughts on how to get this functionality to work as desired?
Thanks,
Chris