2

I have the below graph. A league (l1) starts with LEVEL r1 and the NEXT levels are related using NEXT relationship as shown.

league-[:LEVEL]->r1-[:NEXT]->r2-[:NEXT]->r3-[:NEXT]->r4

What I am looking for is to find all the levels for a given league and in the order. So, for the above graph the expected output is r1, r2, r3, r4. I've the below query but it is returning all the paths.

start l1=node(9)  match l1-[:level]->(level) with level match p=level-[:next*]->(remainingLevels) return p;

Cyphers for creating this graph. This is already setup on console.neo4j.org (make sure to change the id's)

CREATE (l1 {name: 'l1'}) return l1;
CREATE (r1 {name: 'r1'}) return r1;
START l1=node(9), r1=node(10) CREATE l1-[r:level]->r1;
CREATE (r2 {name: 'r2'}) return r2;
START r1=node(10), r2=node(11) CREATE r1-[r:next]->r2;
CREATE (r3 {name: 'r3'}) return r3;
START r2=node(11), r3=node(12) CREATE r2-[r:next]->r3;
CREATE (r4 {name: 'r4'}) return r4;
START r3=node(12), r4=node(13) CREATE r3-[r:next]->r4;
Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
  • It would be useful if you could setup something at console.neo4j.org that we could work with. – Edward Aug 13 '13 at 18:16
  • @Edward Done setting the nodes and relations on console.neo4j.org. I ran my query as well to make sure it is working. Please check and see if you can find a simplified or optimized query. – Aravind Yarram Aug 13 '13 at 18:23
  • You should have a "share" button on that page. If you could [edit] that link into your question, I'll check it out. – Edward Aug 13 '13 at 18:36
  • @Edward Here you go: http://console.neo4j.org/r/gi6zz3 – Aravind Yarram Aug 13 '13 at 18:38

3 Answers3

4

I cleaned up your data set and attempted an answer here:

MATCH league-[r:level|next*]->(level) 
WHERE league.name?="l1" 
RETURN level, length(r) AS Dist, r 
ORDER BY length(r)

The query starts at a league (l1) and traces out across all :level and :next routes and then returns the nodes found sorted by the distance of the route taken to to arrive at it from the starting node.

Note this finds all possible routes, so if there are muliple ways to get to to the level, it won't work very well. That said, it appears your graph is quite tree-like (no cycles) and this will work fine.

This a 2.0 query because it relies on the WHERE query to utilize the indicies to get the starting node in the graph (l1).

Edward
  • 3,292
  • 1
  • 27
  • 38
1

I managed to get this working with the below query.

start l1=node(9) 
match l1-[:level]->(level) 
with level 
match p = level-[:next*]->(remainingLevels) 
with level, max(length(p)) as maxlen 
match p = level-[:next*]->(remainingLevels) 
where length(p)=maxlen
return nodes(p);

Output

+-----------------------------------------------------------------------------------+
==> | nodes(p)                                                                          |
==> +-----------------------------------------------------------------------------------+
==> | [Node[10]{name:"r1"},Node[11]{name:"r2"},Node[12]{name:"r3"},Node[13]{name:"r4"}] |
==> +-----------------------------------------------------------------------------------+

Any simplification or optimizations are welcome.

Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327
1

How about this query,

Match p=league1-[:level]->(level)-[:next*]->endLevel

WHERE league1.name ?= 'l1' AND NOT (endLevel-[:next]->())

RETURN tail(nodes(p))

Lisa Li
  • 2,562
  • 15
  • 11
  • This returns nothing even after converting LEVEL and NEXT to lowercase – Aravind Yarram Aug 13 '13 at 19:15
  • I modified the query to exactly fit the graph in the console, Match p=league1-[:level]->(level)-[:next*]->endLevel WHERE league1.name ?= 'l1' AND NOT (endLevel-[:next]->()) RETURN tail(nodes(p)) – Lisa Li Aug 13 '13 at 19:48