Control apoc.trigger's state (pause or resume) by given condition

zhangjelly66
Node Clone

Hello,
I have a problem to control apoc.trigger's state (pause or resume) by given condition.I've did the research about the manual and website and found nothing relative content about this. Here is the my whole question:

Expected Goal

I want to complete a series transactions by apoc.trigger, and I hope defferent packs of apoc change their state(pause or resume) by given condition.

Goal Example

exsited apoc.trigger:
apoc.trigger1,apoc.trigger2,apoc.trigger3,apoc.trigger4*
Here is a node with a property "state", when the node.state=1, the apoc.trigger1 and apoc.trigger3 change their state to "pause". When node.state=2,apoc.trigger2 and apoc.trigger4 change state to "pause" etc , like this kind of control.

My Method and Experiment

I use the nested apoc.trigger to complete my goal.
here is the code:

call apoc.trigger.add('insipient','
    unwind apoc.trigger.propertiesByKey($assignedNodeProperties,"state") as map
    with map.node as node
    where node.state=0
    apoc.trigger.pause("createMethod")
',{})

Error:

How to Reproduce the Problem

node:

CREATE (:scenario {state: 0, name: "street"})
CREATE (:test {type: 1}),(:test{class: "apple"})

existed apoc:

call apoc.trigger.add('classify',' 
    unwind apoc.trigger.propertiesByKey($assignedNodeProperties,"type") as map
    with map.node as node
    match(n:test{class:"apple"})
    with node,n
    where node.type=1
    create(node)-[r:isA]->(n)
',{})

Specifications

3X_1_4_140bd3945e457e899f3f2ea8544cba045cbdc310.png

Is there anyone could give me some clues to realize my goal or any suggestion to my method...?

Jelly

1 ACCEPTED SOLUTION

giuseppe_villan
Graph Fellow

@zhangjelly66

I think a good solution would be to use the apoc.do.case procedure together with the trigger procedure.

For example, given these 5 triggers:

CALL apoc.trigger.add('triggerZero','UNWIND $createdNodes AS n SET n.triggerZero = timestamp()',{});
CALL apoc.trigger.add('triggerOne','UNWIND $createdNodes AS n SET n.triggerOne = timestamp()',{});
CALL apoc.trigger.add('triggerTwo','UNWIND $createdNodes AS n SET n.triggerTwo = timestamp()',{});
CALL apoc.trigger.add('triggerThree','UNWIND $createdNodes AS n SET n.triggerThree = timestamp()',{});
CALL apoc.trigger.add('triggerFour','UNWIND $createdNodes AS n SET n.triggerFour = timestamp()',{});

you could execute this "super-trigger" :
call apoc.trigger.add('stateTrigger','
unwind apoc.trigger.propertiesByKey($assignedNodeProperties, "state") as map
with map.node as node
where node:StateNode // to ensure we get the right node
with node.state as state // get the state property
CALL apoc.do.case([
state = 0,
"CALL apoc.trigger.pause($zero) yield name return name",
state = 1,
"CALL apoc.trigger.pause($one) yield name with name as ignore CALL apoc.trigger.pause($two) yield name return name",
state = 2,
"CALL apoc.trigger.pause($three) yield name with name as ignore CALL apoc.trigger.pause($four) yield name return name",
state = 3,
"CALL apoc.trigger.resume($three) yield name with name as ignore CALL apoc.trigger.resume($four) yield name return name",
state = 4,
"CALL apoc.trigger.resume($one) yield name with name as ignore CALL apoc.trigger.resume($two) yield name return name",
state = 5,
"CALL apoc.trigger.resume($zero) yield name return name"
], 
"RETURN 1",
{zero: "triggerZero", one: "triggerOne", two: "triggerTwo", three: "triggerThree", four: "triggerFour"})
YIELD value
return 1
',{})

which listens for the state property of a node with label StateNode,
and:

  • if state = 0 : pause triggerZero
  • if state = 1 : pause triggerOne and triggerTwo
  • if state = 2 : pause triggerThree and triggerFour
  • if state = 3 : resume triggerOne and triggerTwo
  • if state = 4 : resume triggerThree and triggerFour
  • if state = 5 : resume triggerZero
  • otherwise do nothing ("return 1")


Just for completeness, your solution doesn't work because there is a syntax error,
the apoc.trigger.pause require a call before it.

View solution in original post

4 REPLIES 4

giuseppe_villan
Graph Fellow

@zhangjelly66

I think a good solution would be to use the apoc.do.case procedure together with the trigger procedure.

For example, given these 5 triggers:

CALL apoc.trigger.add('triggerZero','UNWIND $createdNodes AS n SET n.triggerZero = timestamp()',{});
CALL apoc.trigger.add('triggerOne','UNWIND $createdNodes AS n SET n.triggerOne = timestamp()',{});
CALL apoc.trigger.add('triggerTwo','UNWIND $createdNodes AS n SET n.triggerTwo = timestamp()',{});
CALL apoc.trigger.add('triggerThree','UNWIND $createdNodes AS n SET n.triggerThree = timestamp()',{});
CALL apoc.trigger.add('triggerFour','UNWIND $createdNodes AS n SET n.triggerFour = timestamp()',{});

you could execute this "super-trigger" :
call apoc.trigger.add('stateTrigger','
unwind apoc.trigger.propertiesByKey($assignedNodeProperties, "state") as map
with map.node as node
where node:StateNode // to ensure we get the right node
with node.state as state // get the state property
CALL apoc.do.case([
state = 0,
"CALL apoc.trigger.pause($zero) yield name return name",
state = 1,
"CALL apoc.trigger.pause($one) yield name with name as ignore CALL apoc.trigger.pause($two) yield name return name",
state = 2,
"CALL apoc.trigger.pause($three) yield name with name as ignore CALL apoc.trigger.pause($four) yield name return name",
state = 3,
"CALL apoc.trigger.resume($three) yield name with name as ignore CALL apoc.trigger.resume($four) yield name return name",
state = 4,
"CALL apoc.trigger.resume($one) yield name with name as ignore CALL apoc.trigger.resume($two) yield name return name",
state = 5,
"CALL apoc.trigger.resume($zero) yield name return name"
], 
"RETURN 1",
{zero: "triggerZero", one: "triggerOne", two: "triggerTwo", three: "triggerThree", four: "triggerFour"})
YIELD value
return 1
',{})

which listens for the state property of a node with label StateNode,
and:

  • if state = 0 : pause triggerZero
  • if state = 1 : pause triggerOne and triggerTwo
  • if state = 2 : pause triggerThree and triggerFour
  • if state = 3 : resume triggerOne and triggerTwo
  • if state = 4 : resume triggerThree and triggerFour
  • if state = 5 : resume triggerZero
  • otherwise do nothing ("return 1")


Just for completeness, your solution doesn't work because there is a syntax error,
the apoc.trigger.pause require a call before it.

I will apply this solution on my project, thank your for your patient anwser!

glilienfield
Ninja
Ninja

I think the error in your first post is a result of the ‘pause’ clause. According to the documentation, pause is a procedure, so it needs to be preceded with ‘Call’.

Oh thank you for your help~