0
votes

I have a linked list that is modelled in a circular fashion like so:

(u:User)
-[:LINK]->(a:NODELINK {linkId: 'aa'})
-[:LINK]->(b:NODELINK {linkId: 'bb'})
-[:LINK]->(c:NODELINK {linkId: 'cc'})
-[:LINK]->(d:NODELINK {linkId: 'dd'})
-[:LINK]->(u)

When I query it starting at node (b:NODELINK {linkId: 'bb'}) I would like to match all nodes until I get to the end/start of the list. (The User node)

When I run the following query:

MATCH (u:USER)
WITH u
MATCH (nl:NODELINK)-[:LINK*]->(m)
WHERE nl.linkId = 'bb' AND m <> u
RETURN m

It returns me the following nodes

(3:NODELINK {linkId:'cc'})
(4:NODELINK {linkId:'dd'})
(1:NODELINK {linkId:'aa'})
(2:NODELINK {linkId:'bb'})

As you can see my query wraps around and starts returning nodes from the start of the list. I would like to terminate at the User node and only return the nodes before the end of the list

(3:NODELINK {linkId:'cc'})
(4:NODELINK {linkId:'dd'})

I have created a graph that demonstrates the issue here

How do I query so as to start at the node link of interest and returns all nodes before it reaches the User node?

2

2 Answers

0
votes

Try below query. I think you should bring the NODELINK where you want to begin traversing in the first MATCH clause as it will pin point your graph where to start instead of just matching user node on USER label.

MATCH (nl:NODELINK)
WHERE nl.linkId = 'aa'
WITH nl
MATCH p=(nl)-[:LINK*1..]->(m:USER)
RETURN filter(t IN nodes(p) 
              WHERE t <> nl) AS nodes
0
votes

Your WHERE clause limits the first and last node in the path, but not the intermediate ones, so yes, the query can match paths that include the user node.

Instead of matching many paths and returning only the end nodes, try matching one path from the 'cc' node to the user node, and return all nodes in that path (except the last one if you don't want the user node).

MATCH path=(nl:NODELINK {linkId:'cc'})-[:LINK*]->(u:USER)
RETURN nodes(path)

or

RETURN nodes(path)[..-1]

if you want to return all the nodes except the last one.