Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
06-08-2020 12:43 AM
Hi Team,
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?
Solved! Go to Solution.
06-08-2020 02:56 AM
06-08-2020 01:29 AM
06-08-2020 01:54 AM
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.
06-08-2020 02:38 AM
Did you to use UNWIND
for your iteration?
Regards,
Cobra
06-08-2020 02:48 AM
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
Result :
Now you can notice that risk score is remain same for each iteration, but ideal behaviour is risk score will keep on changing over each iteration .
06-08-2020 02:56 AM
06-08-2020 03:19 AM
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
return value
Now value is changing over each iteration
06-08-2020 03:27 AM
Nice, I'm happy to hear it, good job
All the sessions of the conference are now available online