I have a cypher query which is basically an algorithm which i need to iterate multiple times in order to get the final result. It's same like how we set iteration options in GDS libraries.
I have tried using foreach with range and it throws an error " Invalid use of match inside foreach". What could be the possible ways to add for loop like functionality in graph?
sure, here is one algorithm we have created for risk propagation among Person node based on their interaction with each other.
with 0.8 as Decay, 20 as itr
match (p:Person)-[r:MET_EVENT]->(a:Person) where r.timeEnd>Datetime()-Duration('P14D')
with toFloat(SUM(a.riskScore))/toFloat(count(a)) * Decay as score,p
FOREACH ( ignoreMe in CASE WHEN p.riskScore<score THEN [1] ELSE END | set p.riskScore=score )
return SUM(p.riskScore) as totalRiskScore
Note : this query i need to run more than 20 + time till there is convergence . My aim is to iterate the query till totalRiskScore is converged to a point, when there is no further change in score. That can be achieved by iterating this query over 20 - 25 times. Now how i would iterate this query multiple times.
yes, i have tried with unwind too, but in case of unwind, query is iterative over a given range, but value of result is not getting changes.
See the code snippet with unwind -
UNWIND range(0,10) as iterations
with 0.8 as Decay, 20 as itr, iterations
match (p:Person)-[r:MET_EVENT]->(a:Person) where r.timeEnd>Datetime()-Duration('P14D')
with toFloat(SUM(a.riskScore))/toFloat(count(a)) * Decay as score,p, iterations
FOREACH ( ignoreMe in CASE WHEN p.riskScore<score THEN [1] ELSE END | set p.riskScore=score )
return SUM(p.riskScore) as totalRiskScore,iterations
finally i found the way using your shared document. I am using apoc.cypher.doIt -> as i am modifying records also. Run is for only reading the records.
Upadted snippet is
UNWIND range(0,100) as iterations
call apoc.cypher.doIt("
with 0.8 as Decay, 20 as itr
match (p:Person)-[r:MET_EVENT]->(a:Person) where r.timeEnd>Datetime()-Duration('P14D')
with toFloat(SUM(a.riskScore))/toFloat(count(a)) * Decay as score,p
FOREACH ( ignoreMe in CASE WHEN p.riskScore<score THEN [1] ELSE END | set p.riskScore=score )
return SUM(p.riskScore) as totalRiskScore
",{}) yield value