Cypher query for assigning property values in an arbitrary number of nodes

Viewed 52

I am a Neo4J beginner, so, apologies in advance if my question is too trivial.

I am trying to create a Neo4J graph representing a set of consecutive steps in a game, as shown in this diagram.

You will see in the diagram that I start with zero points, and, at certain steps (but not in every step), additional points are accumulated.

I want to assign points to nodes that don't have points yet, according to the following principle: whenever a node does not have points, I want to assign to it a number of points equal to the points possessed by the closest previous node that has points assigned to it. In the sample diagram, step 2 would have 0 points (:Step {id: 2, points_so_far: 0}), and step 4 would have 1 point (:Step {id: 4, points_so_far: 1}). Note that there may be an arbitrary number of scoreless nodes between nodes that do have a score.

Any help in creating a respective Cypher query would be much appreciated!

Many thanks in advance!

1 Answers

Here is a way to do it :

match (s:Step) WHERE not exists(s.points_so_far) 
match (prev:Step)<-[:HAS_PREVIOUS_STEP*]-(s) where exists(prev.points_so_far) 
with s, head(collect(prev)) as prev
SET s.points_so_far = prev.points_so_far

How does it work ?

First, find all nodes that have no points_so_far

match (s:Step) WHERE not exists(s.points_so_far) 

with that nodes, find all previous steps that have points_so_far

match (prev:Step)<-[:HAS_PREVIOUS_STEP*]-(s) where exists(prev.points_so_far) 

get all the previous nodes with points, collect them in a list, and keep only the first one encountered

with s, head(collect(prev)) as prev

set the value of the node, with the value of the previous node

SET s.points_so_far = prev.points_so_far

Note: This request uses variable path length (the * in <-[:HAS_PREVIOUS_STEP*]-) wich has some performance cost.

Related