问题
I have the following APOC trigger which contains a apoc procedure. This works as desired but I am wondering if I used a lot of WITH statements, is that the way to go? or is there a better way to refactor this code. I am still new to neo4j so not sure.
The control flow- Whenever the Enrollment node is created, it creates an SPerson node and depending on the size(number of SPerson nodes) it creates an enrolled or waitlist(if size>3, and deletes enrolled relation) relation with the course node.
CALL apoc.trigger.add('loadEnrollments',
"UNWIND apoc.trigger.nodesByLabel($assignedLabels, 'Enrollment') AS node
MERGE (p1:SPerson { name: node.name, cell: node.cell, created_at: node.created_at})
WITH p1, node
MATCH (c:Course {name: 'Paradigm Shifting 101'})
WITH node
MATCH (n:SPerson)
WITH node, COUNT(n) as size
CALL apoc.do.when(
size>3,
'MATCH(p1:SPerson),(c:Course)
WHERE p1.name=node.name
CREATE (p1)-[:Waitlist]->(c)
WITH p1,c
MATCH (e:Enrollment) DETACH DELETE e',
'MATCH(p1:SPerson),(c:Course)
WHERE p1.name=node.name
CREATE (p1)-[:Enrolled]->(c)
WITH p1,c
MATCH (e:Enrollment) DETACH DELETE e', {node:node}) YIELD value
DETACH DELETE node",
{ phase: 'after' });
回答1:
You should:
- minimize the number of rows of data that have to be processed for a query, and
- not repeat operations unnecessarily.
With those rules in mind, this query may work (efficiently) for you:
CALL apoc.trigger.add(
'loadEnrollments',
"
CALL apoc.cypher.doIt('MATCH (e:Enrollment) DETACH DELETE e', {}) YIELD value
WITH value
MATCH (n:SPerson)
WITH COUNT(n) as size
MATCH (c:Course {name: 'Paradigm Shifting 101'})
UNWIND apoc.trigger.nodesByLabel($assignedLabels, 'Enrollment') AS node
MERGE (p1:SPerson {name: node.name, cell: node.cell, created_at: node.created_at})
DETACH DELETE node
CALL apoc.create.relationship(p1, CASE WHEN size > 3 THEN 'Waitlist' ELSE 'Enrolled' END, {}, c) YIELD rel
",
{ phase: 'after' }
);
来源:https://stackoverflow.com/questions/62943204/neo4j-questions-on-syntax-apoc-trigger