Search code examples
javasortingtraversalarangodb

Arangodb Java-driver Sort paths


Please, can you explain me how I can sort paths. Now I have next code

TraversalOptions options = new TraversalOptions()
                    .edgeCollection("edges")
                    .startVertex("nodes/9149892904413851091")
                    .verticesUniqueness(TraversalOptions.UniquenessType.path)
                    .direction(TraversalOptions.Direction.any)
                    .strategy(TraversalOptions.Strategy.depthfirst)
                    .order(TraversalOptions.Order.preorder)
                    .minDepth(5)
                    .maxDepth(5);
            System.out.println("1");
            TraversalEntity<BaseDocument, BaseEdgeDocument> traversal = 
            db.executeTraversal(BaseDocument.class, BaseEdgeDocument.class, options);

How I understand .sort method in options will sort edges. But I want to sort paths. Any ideas?

I need to test two cases: 1. sort by length of paths ( so I will find the shortest path) 2. sort by sum of relationships' weights (so i will be able to find a path with the less weight)


Solution

  • Achieving your goal is both easier and much more efficient using an AQL query than a Traversal.

    A (parameterized) AQL query for a shortest path looks like this:

    FOR v IN ANY SHORTEST_PATH
    @startVertex TO @targetVertex
    edges
    RETURN v
    

    To get a weighted shortest path (i.e., shortest in terms of sum of the weights), just specify the name of the weight attribute:

    FOR v IN ANY SHORTEST_PATH
    @startVertex TO @targetVertex
    edges
    OPTIONS { weightAttribute: "weight" }
    RETURN v
    

    You can use an AQL query in Java like this:

    // Set the query parameters
    Map<String, Object> bindVars
        = new MapBuilder()
        .put("startVertex", "nodes/1234")
        .put("targetVertex", "nodes/5678")
        .get();
    
    // execute the query
    ArangoCursor<BaseDocument> cursor = arango.db("mydb").query(
        "FOR v IN ANY SHORTEST_PATH "
            + "@startVertex TO @targetVertex "
            + "edges "
            + "OPTIONS { weightAttribute: 'weight' } "
            + "RETURN v",
        bindVars,
        null,
        BaseDocument.class
    );
    
    // do something with the results
    cursor.forEach((v) -> {
        System.out.println(v);
    });