Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-23-2020 05:29 PM
I pick a node, lets say 'p4', then find all of its parents. I am interested in tagging all nodes that are connected to 'p4 with a label that represents how far they are from 'p4'. I came up with the code below.
MATCH upstream_path = (interesting_part:Part{PART_NAME:'p4'})-[:CHILD_OF*0..4]->(upstream_part:Part)
WHERE length(upstream_path) < 5
WITH length(upstream_path) as level, nodes(upstream_path)[-1] as parents
CALL apoc.create.addLabels(parents, ['Level' + toString(level)]) YIELD node
RETURN count(parents) as count
However, i soon realized if there is a cycle in my graph, a node connecting to 'p4' can be assigned several new labels/levels/distances. For example, we can reach to a 'p4' neighboring node directly, or go through loop and reach it. In this case we will have 2 different distances assigned to that neighboring node. I would like to prevent this from happening. If i have already assigned a 'Level' Label to a node, i do not want to create another one.
I tried to use a CASE WHEN
, but do not know how to call a cypher function inside it, and this fails.
MATCH upstream_path = (interesting_part:Part{PART_NAME:'p4'})-[:CHILD_OF*0..4]->(upstream_part:Part)
WHERE length(upstream_path) < 5
WITH length(upstream_path) as level, nodes(upstream_path)[-1] as parents, interesting_part
WITH length([x IN labels(parents) WHERE x STARTS WITH 'Level']) AS result, parents
WITH CASE result WHEN 0 THEN CALL apoc.create.addLabels( parents, ['Level' + toString(level)]) YIELD node ELSE 1 END AS output
RETURN output
Finally, i would really appreciate to know if there is a way for me to down-sample when showing the graph results. If i have thousands of nodes connected to 'p4', the graph can become really big to show. Is there a way to sample for example only 10 paths connecting to 'p4' rather than all paths connecting to 'p4' (e.g., can i put a limit statement in the middle of a cypher query?)
as a toy example you can try the following graph and notice 'p2' getting 2 labels.
CREATE (p1:Part{PART_NAME:'p1'})
CREATE (p2:Part{PART_NAME:'p2'})
CREATE (p3:Part{PART_NAME:'p3'})
CREATE (p4:Part{PART_NAME:'p4'})
CREATE (p5:Part{PART_NAME:'p5'})
CREATE (p6:Part{PART_NAME:'p6'})
CREATE (p2)-[:CHILD_OF]->(p1)
CREATE (p3)-[:CHILD_OF]->(p1)
CREATE (p4)-[:CHILD_OF]->(p2)
CREATE (p6)-[:CHILD_OF]->(p2)
CREATE (p2)-[:CHILD_OF]->(p5)
CREATE (p5)-[:CHILD_OF]->(p2)
03-25-2020 02:38 AM
CASE will only return a value.
Have a look at procedure apoc.do.case
, that should let run a create query conditionally.
In pure cypher, the following "trick" would also work :
FOREACH (i IN CASE result WHEN 0 THEN [1] ELSE [] END | <do stuff here>)
You can use LIMIT
after a WITH
statement.
03-25-2020 02:21 PM
Please see our knowledge base article on conditional Cypher execution for an explanation and various solutions.
All the sessions of the conference are now available online