Search code examples
traversalarangodbaql

How to merge aql query with iterative traversal


I want to query a collection in ArangoDB using AQL, and at each node in the query, expand the node using a traversal.

I have attempted to do this by calling the traversal as a subquery using a LET statement within the collection query. The result set for the traversal is empty, even though the query completes.

FOR ne IN energy
    FILTER ne.identifier == "12345"
    LET ne_edges = (
    FOR v, e IN 1..1 ANY ne relation
        RETURN e
    )
    RETURN MERGE(ne, {"edges": ne_edges})

[
  {
    "value": 123.99,
    "edges": []
  }
]

I have verified there are edges, and the traversal returns correctly when it is not executed as a subquery.

It seems as if the initial query is completing before a result is returned from the subquery, giving the result below.

What am I missing? or is there a better way?


Solution

  • I can think of two way to do this. This first is easier to understand but the second is more compact. For the examples below, I have a vertex collection test2 and an edge collection testEdge that links parent and child items within test2

    Using Collect:

    let seed = (FOR testItem IN test2
                FILTER testItem._id in ['test2/Q1', 'test2/Q3'] 
                RETURN testItem._id)
    
    let traversal = (FOR seedItem in seed
        FOR v, e IN 1..1 ANY seedItem
        testEdge
    RETURN {seed: seedItem, e_to: e._to})
    
    for t in traversal
    COLLECT seeds = t.seed INTO groups = t.e_to
    return {myseed: seeds, mygroups: groups}
    

    Above we first get the items we want to traverse through (seed), then we perform the traversal and get an object that has the seed .id and the related edges Then we finally use collect into to group the results

    Using array expansion

    FOR testItem IN test2
        FILTER testItem._id in ['test2/Q1', 'test2/Q3']
        LET testEdges = (
        FOR v, e IN 1..1 ANY testItem testEdge
            RETURN e
        )
    RETURN {myseed: testItem._id, mygroups: testEdges[*]._to}
    

    This time we combine the seed search and the traversal by using the let statement. then we use array expansion to group items

    In either case, I end up with something that looks like this:

    [
      {
        "myseed": "test2/Q1",
        "mygroups": [
          "test2/Q1-P5-2",
          "test2/Q1-P6-3",
          "test2/Q1-P4-1"
        ]
      },
      {
        "myseed": "test2/Q3",
        "mygroups": [
          "test2/Q3",
          "test2/Q3"
        ]
      }
    ]