Search code examples
amazon-web-servicesgremlinamazon-neptunegremlinpython

How can I do conditional sort on Gremlin/Neptune


I am trying to build a query that will return a Vertex both edges, and sort them conditionally by value of a different property according to whether the original Vertex is the out Vertex or in Vertex in the given edge, I have two properties that will comply with this sort ("origin_pinned" & "target_pinned"), if an edge in Vertex is the original vertex I want to use "origin_pinned" value if its the out vertex then I want to use "target_pinned" value

This must be one query

I tried to run the following query but does not seem to have effect:

g.V('id123').bothE().order().by(values(choose(inV().is(V('id123')), 
constant('origin_pinned'), constant('target_pinned'))), desc)

Solution

  • The values step will not work the way you are trying to use it. You did not include any sample data in the question, but using the air-routes data set, the query can most likely be simplified as shown below:

    gremlin> g.V(44).as('a').
    ......1>   bothE().
    ......2>   order().
    ......3>     by(coalesce(
    ......4>         where(inV().as('a')).constant('origin_pinned'),
    ......5>         constant('target_pinned')))
    
    ==>e[57948][3742-contains->44]
    ==>e[54446][3728-contains->44]
    ==>e[4198][13-route->44]
    ==>e[4776][31-route->44]
    ==>e[4427][20-route->44]
    ==>e[4015][8-route->44]
    ==>e[5061][44-route->8]
    ==>e[5062][44-route->13]
    ==>e[5063][44-route->20]
    ==>e[5064][44-route->31] 
    

    and to prove the reverse also works

    gremlin> g.V(44).as('a').
    ......1>   bothE().
    ......2>   order().
    ......3>     by(coalesce(
    ......4>         where(outV().as('a')).constant('origin_pinned'),
    ......5>         constant('target_pinned')))
    
    ==>e[5061][44-route->8]
    ==>e[5062][44-route->13]
    ==>e[5063][44-route->20]
    ==>e[5064][44-route->31]
    ==>e[57948][3742-contains->44]
    ==>e[54446][3728-contains->44]
    ==>e[4198][13-route->44]
    ==>e[4776][31-route->44]
    ==>e[4427][20-route->44]
    ==>e[4015][8-route->44]     
    

    To check things are working as expected, we can do:

    gremlin> g.V(44).as('a').
    ......1>   bothE().as('e').
    ......2>   coalesce(
    ......3>     where(inV().as('a')).constant('origin_pinned'),
    ......4>     constant('target_pinned')).as('p').
    ......5>     order().
    ......6>   select('e','p')
    
    ==>[e:e[57948][3742-contains->44],p:origin_pinned]
    ==>[e:e[54446][3728-contains->44],p:origin_pinned]
    ==>[e:e[4198][13-route->44],p:origin_pinned]
    ==>[e:e[4776][31-route->44],p:origin_pinned]
    ==>[e:e[4427][20-route->44],p:origin_pinned]
    ==>[e:e[4015][8-route->44],p:origin_pinned]
    ==>[e:e[5061][44-route->8],p:target_pinned]
    ==>[e:e[5062][44-route->13],p:target_pinned]
    ==>[e:e[5063][44-route->20],p:target_pinned]
    ==>[e:e[5064][44-route->31],p:target_pinned]