3

Sorting traversal paths based on Edge property and Dedup

Hello, I'm having a in memory graph and I want to sort paths based on Edge property and also dedup where paths leading to same destination.

E.g.

    String NAME = "name";
   String id = "id";
    g.addV().property(id, 1).property(NAME, "u1").as("u1")
            .addV().property(id, 2).property(NAME, "u2").as("u2")
            .addV().property(id, 3).property(NAME, "u3").as("u3")
            .addV().property(id, 4).property(NAME, "u4").as("u4")
            .addE(rel).from("u2").to("u1").property("order", 2)
            .addE(rel).from("u3").to("u1").property("order", 1)
            .addE(rel).from("u4").to("u2").property("order", 3)
            .addE(rel).from("u4").to("u3").property("order", 4)
            .iterate();

What I'm trying to achieve is a traversal which gives me only one path i.e.

vertices = [path[u1, u3, u4]].

I tried using below gremlin.

    List<Path> maps = g.V()
                .has("id", 1)
                .repeat(in()
                        .simplePath())
                .until(inE().count().is(0))
                .order().by(outE("rel").values("order"),Order.asc)
                .path().by("name")
                .toList();

However sorting doesn't happen. It gives me two paths : vertices = [path[u1, u2, u4], path[u1, u3, u4]]

But I'm looking for output as vertices = [path[u1, u3, u4]]

I'm new to gremlin and ran out of options to try. can someone help ?

Ketan Dhamasana
  • 61
  • 1
  • 1
  • 7
  • Could you clarify the sorting rules? Paths usually have more than 1 edge. Do you want to order by the sum of all `order` property values on the path or only the last `order` value? Same for `dedup()`, what's your rule? Deduplicate by the last vertex? The first and the last vertex? – Daniel Kuppitz Jul 29 '19 at 14:47

2 Answers2

2
g.V() 
.has("id", 1) 
.repeat(in("rel") .order() .by(outE().values("order"), Order.asc) .simplePath() )
.until(inE().count().is(0)) 
.dedup() 
.path() 
.by("name") 
.toList() ;
Ketan Dhamasana
  • 61
  • 1
  • 1
  • 7
0

Using toList will give you all the passible traversals. In your case you did order the answers but didn't take only the first one.

You should add limit step:

...
.limit(1).toList()

Or you can use next() instead of toList()

noam621
  • 2,766
  • 1
  • 16
  • 26
  • Thanks @noam621 for replying. limiting to 1 will give me only first path. I want all possible distinct paths for leaf nodes. Which should be picked up by their Edge property and then limit to 1 so that I get paths which are having priority based on their edge property. – Ketan Dhamasana Jul 30 '19 at 11:48
  • Ok, Can you supply a more complicated example with the expected result? – noam621 Jul 30 '19 at 12:04
  • 1
    I tried pasting my sample graph but seems stackoverflow has limitation on commets text size. But I found solution as below. – Ketan Dhamasana Jul 31 '19 at 14:04
  • 1
    g.V() .has("id", 1) .repeat(in("rel") .order() .by(outE().values("order"), Order.asc) .simplePath() ) .until(inE().count().is(0)) .dedup() .path() .by("name") .toList() ; – Ketan Dhamasana Jul 31 '19 at 14:04