Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
09-30-2018 09:04 AM
Hi, there. I've been struggling with this for a bit, so I thought I'd ask here.
How can I get a breadcrumb-like string of the parent/child relationships of nodes in a nested structure?
I basically have a hierarchical group structure that I'm trying to represent, almost like a directory path. It doesn't go very many levels deep (just 3-4), and it doesn't loop or otherwise go infinite.
I'm trying to create strings (as node properties) like this:
'/Root/group/subgroup1/subgroup2' for Group node subgroup2
'/Root/group/subgroup1' for Group node subgroup1
'/Root/group' for Group node group
and just 'Root' for any of the root Group nodes
I can get pretty close with the Cypher below for a single level, but I can't figure out if/how I need to do this recursively or otherwise.
MATCH (p:Group)-[:CONTAINS]->(m:Group) RETURN "/" + p.name + "/" + m.name as trail
which returns strings like this for each node that is contained by another.
"/Group/subgroup"
I've played around with using APOC to expand and UNWIND nodes in a subgraph, too. I need to figure out how to chase back up to the root, and only run down to the current node (and not beyond).
Any suggestions...?
10-01-2018 04:37 AM
So for this one, apoc.text.join()
will be a big help.
The idea is, given the name of a group (we're assuming group names are unique), we'll use a variable-length relationship to define a pattern that goes up to a root :Group node (we ensure it's a root node by making a restriction that there is no :CONTAINS relationship to it).
Once we have that path, from root to the node in question, we take the nodes of that path and extract the name for each node, then we'll use the join function to place a slash between each name:
MATCH path = (root:Group)-[:CONTAINS*]->(m:Group)
WHERE m.name = $name AND NOT ()-[:CONTAINS]->(root)
WITH [node in nodes(path) | node.name] as trailNames
RETURN "/" + apoc.text.join(trailNames, "/") as trail
10-01-2018 07:10 AM
Thanks, Andrew. That did the trick.
I made a slight modification since I just need the whole list and not a parameterized $name value.
MATCH path = (root:Group)-[:CONTAINS*]->(m:Group)
WHERE NOT ()-[:CONTAINS]->(root)
WITH [node in nodes(path) | node.name] as trailNames
RETURN "/" + apoc.text.join(trailNames, "/") as trail
Actually, I'm doing this as part of an import and need to set each group to have a property. But I have enough to work with here.
All the sessions of the conference are now available online