Search code examples
graphgremlintinkerpop3amazon-neptune

Gremlin get vertices where there exists a bidirectional edge connecting them


Mine is a simple social network scenario people make friends and post pictures and those pictures should be visible to people only if there exists a 2 way relation ship between them

g.addV("user").property("name","X").as('x').
  addV("user").property("name","Y").as('y').
  addV("post").property("name","p1").as('p1').
  addE("posts").from("x").to("p1").
  addE("friend").from("x").to("y").iterate()

right now there exists an only one-way relationship between X and Y. Y should only see the posts of X only if there exists bidirectional relations ship i.e

g.addE("friend").from(V().has("name","Y")).to(V().has("name","X")).iterate()

now there is both way edge of the same type between X and Y so both can view each other posts.

my code to get posts of all friends of Y but not working

g.V("name","Y").both("friend").out("posts").toList().next();

Solution

  • One of the more direct way to write this is with:

    g.V().has("name","Y").as('y').
      out('friend').
      where(__.in('friend').as('y')).
      out('posts').values('name')
    

    So, find "Y" and label that step as "y", then traverse to friends, filter out any "friend" vertices who don't match back to "y" using where() then for those matches get the posts.

    gremlin> g.addV("user").property("name","X").as('x').
    ......1>   addV("user").property("name","Y").as('y').
    ......2>   addV("post").property("name","p1").as('p1').
    ......3>   addE("posts").from("x").to("p1").
    ......4>   addE("friend").from("x").to("y").iterate()
    gremlin> g.V().has("name","Y").as('y').
    ......1>   out('friend').
    ......2>   where(__.in('friend').as('y')).
    ......3>   out('posts').values('name')
    gremlin> g.addE("friend").from(V().has("name","Y")).to(V().has("name","X")).iterate()
    gremlin> g.V().has("name","Y").as('y').
    ......1>   out('friend').
    ......2>   where(__.in('friend').as('y')).
    ......3>   out('posts').values('name')
    ==>p1