jacob3
(Jacob)
January 10, 2024, 5:31pm
1
Hello,
I am attempting to use an apoc.trigger
in order to create a set of nodes after a node - with a specific label - is created. However, it doesn't seem to be working.
I updated/added the apoc.conf
with the appropriate statements to enable apoc.trigger
. I'm able to use apoc.trigger
functions including installing a trigger.
BUT, it's still not working for some reason. When I create new nodes, the trigger is not activated.
Any thoughts on what I may be missing?
@jacob3
Neo4j version?
APOC version?
Can you share the cypher used to create the trigger?
jacob3
(Jacob)
January 10, 2024, 7:29pm
3
Neo4j Version: 5.11 enterprise
APOC Version: 5.11 core
jacob3
(Jacob)
January 10, 2024, 8:36pm
5
Here is the cypher that creates the trigger (in the system
database. I changed the node labels to remove info that I couldn't share.
CALL apoc.trigger.install(
'dev',
'create-class-new-user',
"UNWIND $createdNodes AS n
WHERE n:User AND NOT (n)-[:PREFERS]->(:School)
CREATE (p:School)
SET
p.id = randomUUID(),
p.isPrimary = true,
p.createdAt = datetime(),
p.modifiedAt = datetime()
WITH p
CREATE (d1:Department {name: 'Math'})
SET d1.id = randomUUID(), d1.createdAt = datetime(), d1.modifiedAt = datetime(), d1.isPrimary = false
CREATE (p)-[:HAS_DEPARTMENT]->(d1)
CREATE (d2:Department {name: 'Science'})
SET d2.id = randomUUID(), d2.createdAt = datetime(), d2.modifiedAt = datetime(), d2.isPrimary = false
CREATE (p)-[:HAS_DEPARTMENT]->(d2)
WITH d1, d2
CREATE (t:Category {name:'Monday'})
SET
t.id = randomUUID(),
t.createdAt = datetime(),
t.modifiedAt = datetime()
CREATE (d1)-[:PREFERS]->(t)
CREATE (d2)-[:PREFERS]->(t)
WITH d1, d2
CREATE (t:Category {name:'Tuesday'})
SET
t.id = randomUUID(),
t.createdAt = datetime(),
t.modifiedAt = datetime()
CREATE (d1)-[:PREFERS]->(t)
CREATE (d2)-[:PREFERS]->(t)
WITH d1, d2
CREATE (t:Category {name:'Wednesday'})
SET
t.id = randomUUID(),
t.createdAt = datetime(),
t.modifiedAt = datetime()
CREATE (d1)-[:PREFERS]->(t)
CREATE (d2)-[:PREFERS]->(t)
WITH d1, d2
CREATE (t:Category {name:'Thursday'})
SET
t.id = randomUUID(),
t.createdAt = datetime(),
t.modifiedAt = datetime()
CREATE (d2)-[:PREFERS]->(t)
WITH d1, d2
CREATE (t:Category {name:'Friday'})
SET
t.id = randomUUID(),
t.createdAt = datetime(),
t.modifiedAt = datetime()
CREATE (d1)-[:PREFERS]->(t)", {phase:'afterAsync'})
@jacob3
have u tried with a simpler trigger definition as a means to debug.
Given
UNWIND $createdNodes AS n
WHERE n:User AND NOT (n)-[:PREFERS]->(:School)
CREATE (p:School)
are any :School nodes created?
If you remove the WHERE
clause are any :School nodes created?
jacob3
(Jacob)
January 11, 2024, 1:42am
7
Removing the where clause doesn't seem to work either.
Am I not allowed to create a new node in a trigger?
@jacob3
given the current issue and rather than building out a trigger with a lot of complexity, I decided to build out a very small test case. And with Neo4j 5.11.0 and
ls -al plugins/
drwxr-xr-x 2 neo4j neo4j 4096 Jan 11 22:24 .
drwxr-xr-x 15 neo4j neo4j 4096 Dec 5 11:22 ..
-rw-r--r-- 1 neo4j neo4j 14495768 Jan 11 22:24 apoc-5.11.0-core.jar
-rw-rw-r-- 1 neo4j neo4j 11137885 Dec 5 11:20 apoc-5.11.0-extended.jar
-rw-r--r-- 1 neo4j neo4j 2217 Aug 8 07:47 README.txt
and apoc.conf defined as
cat ../conf/apoc.conf
apoc.trigger.enabled=true
apoc.trigger.refresh=60000
and then i defined trigger as follows
@system> CALL apoc.trigger.install(
'neo4j',
'create-class-new-user',
"UNWIND $createdNodes AS cN create(n:Result {nodes:id(cN)})",{});
which does nothing more than for the nodes creates define a new node :Result
and set its nodes:
property to be the id of the node created.
And thus
@neo4j> match (n:Test) return n;
+---+
| n |
+---+
+---+
0 rows
ready to start consuming query after 96 ms, results consumed after another 3 ms
@neo4j> match (n:Result) return n;
+---+
| n |
+---+
+---+
0 rows
ready to start consuming query after 3 ms, results consumed after another 3 ms
@neo4j> unwind range(1,5) as x create (n:Test {id:x});
0 rows
ready to start consuming query after 8 ms, results consumed after another 0 ms
Added 5 nodes, Set 5 properties, Added 5 labels
@neo4j> match (n:Test) return n.id, id(n);
+--------------+
| n.id | id(n) |
+--------------+
| 1 | 10101 |
| 2 | 10102 |
| 3 | 10103 |
| 4 | 10104 |
| 5 | 10105 |
+--------------+
5 rows
ready to start consuming query after 4 ms, results consumed after another 4 ms
@neo4j> match (n:Result) return n order by n.nodes asc;;
+--------------------------+
| n |
+--------------------------+
| (:Result {nodes: 10101}) |
| (:Result {nodes: 10102}) |
| (:Result {nodes: 10103}) |
| (:Result {nodes: 10104}) |
| (:Result {nodes: 10105}) |
+--------------------------+
5 rows
ready to start consuming query after 73 ms, results consumed after another 7 ms
so would seem to work for me.
1 Like
jacob3
(Jacob)
January 11, 2024, 11:32pm
10
Thanks @dana_canzano for looking into this.
What worked for me was keeping the phase
parameter undefined, i.e. "CALL apoc.trigger.install("", "", {})"
.
Now it's working!
StuMoore
(Stu Moore)
January 12, 2024, 4:54pm
11
There is another option besides APOC, we have introduced Change Data Capture (CDC) in Neo4j, it is currently available as a beta in versions from Neo4j 5.14 Enterprise. You can create selectors which watch for specific labels, when a node is created a change event will be created and you can then use that to perform the desired action Introduction - Change Data Capture
2 Likes