2
votes

I have a pretty standard graphql which represent a tree structure:

graph

I would like to make a graph traversal and force the order according to the order I set on each edge:

A -> C

A -> B -> E

A -> B -> D

I tried to add a SORT on my query, but it sorts the whole resulting array which is not what I want:

FOR v, e, p IN 1..1000 OUTBOUND A
    edge_collec
    SORT e.order
    RETURN v

Is there a way to do this using AQL?

1
As far as I can tell, a different order wouldn't make any difference to the traversal in the provided example. Thus, I wonder if you could sort the results client-side instead. Doing certain things on the server-side can be problematic, see the discussion about enumerating results. What controls the order in which edges are traversed is the doubly-linked list of the hybrid index I suppose (newest edges last?) - CodeManX
How did you want to control the sorting? It looks like in the above example you are sorting the by the name of the last vertex in the path, sorted descending? Remember that the result from your FOR v, e, p query above will be three arrays, and you probably want to look at saving the p result to a variable and then execute additional queries over that. But you'll need to be familiar with the contents of p as it contains paths, which are collections of vertices and edges. - David Thomas
Please include the expected results and the actual results using your letters example. If I understand you correctly, you expected ACBED but got CEABD? - TZubiri
It works as intended, it sorts by order after the traversal. C and E both have order: 0, B and D order: 1, thus C and E are sorted before B and D. Note that the possible return results are CEBD, ECBD, CEDB and ECBD. You should try SORT LENGTH(p.edges), e.order to first sort by path length and by order attribute secondly (for equally long paths). That should give you CBED. - CodeManX
@CoDEmanX Yep SORT LENGTH(p.edges), e.order makes the job. Probably the simplest solution. Feel free to write a proper answer to get the credit - Tdy

1 Answers

3
votes

What the query does is:

  • Follow all outgoing edges in edge collection edge_collec from start vertex A
  • Then sort in ascending order by edge attribute order
  • Return the vertices (the last vertex of each found path)

The edge attribute e.order is either 0 or 1:

  • A --[ order: 1 ]--> B
  • A --[ order: 0 ]--> C
  • B --[ order: 1 ]--> D
  • B --[ order: 0 ]--> E

Sorting by order will return C and E (0) before B and D (1). Because two edges have the same value, it's undefined whether C or E is returned first, and whether B or D is returned third.

If you want the vertices at depth = 1 to be returned before the vertices at depth = 2, but still sort by order on each depth level, you can use:

SORT LENGTH(p.edges), e.order

LENGTH(p.edges) gives you the current depth of the traversal. It first sorts by depth, then by the edge attribute and will give you the desired result order: C B E D