Search code examples
graph-databasesgremlinamazon-neptune

Analysing the edges between two vertices gremlin


Here is my graph

g.addV('user').property('id',1).as('1').
  addV('user').property('id',2).as('2').
  addV('user').property('id',3).as('3').
  addE('follow').from('1').to('2').
  addE('follow').from('1').to('3').iterate()

The below is my approach when a user wants to follow another user suppose 2 wants to follow 3

I'm checking first whether follow edge exist between 2 and 3

if(g.V().has(id, 2).outE(follow).inV().has(id, 3).hasNext())
 {
   //if exists that means he already following him so i'm dropping the follow edge and adding unfollow edge to 2,3.
 }
 else if(g.V().has(id, 2).outE(unfollow).inV().has(id, 3).hasNext())
 {
   //if exists he already unfollowed him and he wants to follow him again i'm dropping the unfollow edge and adding the follow edge to 2,3.
 }
 else 
 {
   // there is no edges between 2,3 so he is following him first so i'm adding follow edge 2,3.
 }

but the drawback of this approach is every time it needs to query 2 times which impacts performance . Can you suggest me a better approach ?


Solution

  • You can build if-then-else semantics with choose(). A direct translation of your logic there would probably look like this:

    gremlin> g.addV('user').property(id,1).as('1').
    ......1>   addV('user').property(id,2).as('2').
    ......2>   addV('user').property(id,3).as('3').
    ......3>   addE('follow').from('1').to('2').
    ......4>   addE('follow').from('1').to('3').iterate()
    gremlin> g.V(3).as('target').
    ......1>   V(2).as('source').
    ......2>   choose(outE('follow').aggregate('d1').inV().hasId(3), 
    ......3>            sideEffect(addE('unfollow').from('source').to('target').
    ......4>                       select('d1').unfold().drop()).constant('unfollowed'),
    ......5>          choose(outE('unfollow').aggregate('d2').inV().hasId(3),
    ......6>                   sideEffect(addE('follow').from('source').to('target').
    ......7>                              select('d2').unfold().drop()).constant('followed'),
    ......8>                 addE('follow').from('source').to('target').constant('followed-first')))
    ==>followed-first
    gremlin> g.E()
    ==>e[0][1-follow->2]
    ==>e[1][1-follow->3]
    ==>e[2][2-follow->3]
    gremlin> g.V(3).as('target').
    ......1>   V(2).as('source').
    ......2>   choose(outE('follow').aggregate('d1').inV().hasId(3), 
    ......3>            sideEffect(addE('unfollow').from('source').to('target').
    ......4>                       select('d1').unfold().drop()).constant('unfollowed'),
    ......5>          choose(outE('unfollow').aggregate('d2').inV().hasId(3),
    ......6>                   sideEffect(addE('follow').from('source').to('target').
    ......7>                              select('d2').unfold().drop()).constant('followed'),
    ......8>                 addE('follow').from('source').to('target').constant('followed-first')))
    ==>unfollowed
    gremlin> g.E()
    ==>e[0][1-follow->2]
    ==>e[1][1-follow->3]
    ==>e[3][2-unfollow->3]
    gremlin> g.V(3).as('target').
    ......1>   V(2).as('source').
    ......2>   choose(outE('follow').aggregate('d1').inV().hasId(3), 
    ......3>            sideEffect(addE('unfollow').from('source').to('target').
    ......4>                       select('d1').unfold().drop()).constant('unfollowed'),
    ......5>          choose(outE('unfollow').aggregate('d2').inV().hasId(3),
    ......6>                   sideEffect(addE('follow').from('source').to('target').
    ......7>                              select('d2').unfold().drop()).constant('followed'),
    ......8>                 addE('follow').from('source').to('target').constant('followed-first')))
    ==>followed
    gremlin> g.E()
    ==>e[0][1-follow->2]
    ==>e[1][1-follow->3]
    ==>e[4][2-follow->3]