arslan
arslan

Reputation: 2224

cypher: how to ensure the order of result list?

I have a list of nodes as an input and I want to find all nodes connected to each node in the given list.

For example, the input is

   [1,2,3,..] . //This could come in any order such as [1,4,2,...]

and output should be

   [[n1,m1,p1,..],[n2,m2,p2,..],,,,]

where

   [n1,m1,p1,..] 

is a list of nodes connected to 1.

so I thought the following should work

 FOREACH (num in [1,2,3] | 
          match (a : a_node {id:num})-[]-(b:b_node)
          with a, collect(b) as set ) 
          return set 

which did not work, so I  tried

          UNWIND  [1,2,3] as num 
          match (a : a_node {id:num})-[]-(b:b_node)
          with a, collect(b) as set  
          return set 

which worked, but the order is wrong. I got the following

         [[n2,m2,p2,..],[n1,m1,p1,..],...]

I tried 'UNWIND', but the order of lists in the output is not correct I need to collect them by the order of elements in the given list. Just need to get the results by the order.

My question is that is my idea correct?
Could anyone point out my mistake here, thanks in advance!

Upvotes: 2

Views: 886

Answers (2)

InverseFalcon
InverseFalcon

Reputation: 30397

For custom ordering by the order given in your list, you'll need to create and use your own list index, and order using that index at the end:

WITH [1,2,3] as num
UNWIND range(0, size(num) - 1) as index
MATCH (a : a_node {id:num[index]})-[]-(b:b_node)
WITH index, a, collect(b) as set  
ORDER BY index ASC
RETURN set

Keep in mind that because of your MATCH, any :a_node that doesn't have a relationship to a :b_node will be excluded in the results (as well as any input id where there is no :a_node with the id), so it's possible your result set size won't be equal to your input list size.

If you know that every id input has an :a_node node, and you want to support cases where there is no connected :b_node, consider doing a MATCH on just the :a_node, and an OPTIONAL MATCH to the b_node. That way you'll correctly get empty sets for :a_nodes that have no :b_node connections.

Here's how that modification would look:

WITH [1,2,3] as num
UNWIND range(0, size(num) - 1) as index
MATCH (a : a_node {id:num[index]})
OPTIONAL MATCH (a)--(b:b_node)
WITH index, a, collect(b) as set  
ORDER BY index ASC
RETURN set

Upvotes: 2

Tomaž Bratanič
Tomaž Bratanič

Reputation: 6514

Ok so what you need to add is ORDER BY. This should work

 UNWIND  [1,2,3] as num 
      match (a : a_node {id:num})-[]-(b:b_node)
      with a, collect(b) as set order by a.id asc
      return set 

Upvotes: 0

Related Questions