3

I am playing with TinkerPop and I am getting my head stuck around this problem : I would like to find all the actors from the movies that ALL my friends liked (in other words, find the common movies that my friends liked and get the name of all the actors that played in those movies)

so far what I tried :

g.V(v1).out("friend").out("like").in("play_in").values("name")

returns all the actors that played in a movie that at least ONE of my friends liked. I am quite new to TinkerPop and the vast API confuses me somehow.

Thanks !

Louis F.
  • 2,018
  • 19
  • 22

1 Answers1

4

As always, let's start with a sample graph:

g = TinkerGraph.open().traversal()
g.addV(id, "user 1").as("u1").
  addV(id, "user 2").as("u2").
  addV(id, "user 3").as("u3").
  addV(id, "movie 1").as("m1").
  addV(id, "movie 2").as("m2").
  addV(id, "movie 3").as("m3").
  addE("friend").from("u1").to("u2").
  addE("friend").from("u1").to("u3").
  addE("like").from("u2").to("m1").
  addE("like").from("u2").to("m2").
  addE("like").from("u3").to("m2").
  addE("like").from("u3").to("m3").iterate()

As you can already see, only movie 2 was liked by all friends of user 1. The traversal to answer the question follows (with comments inline):

gremlin> g.V("user 1").                                               /* start at user 1                       */
           out("friend").aggregate("friends").                        /* collect all his friends               */
           out("like").dedup().                                       /* traverse to all the movies they liked */
           filter(
             __.in("like").where(within("friends")).count().as("a").  /* count the number of friends who liked the movie */
             select("friends").count(local).where(eq("a"))            /* compare to the number of total friends and      */
           )                                                          /*   filter, if the counts don't match             */
==>v[movie 2]

Now, if you want to get the actors names, you only need to append:

.in("play_in").dedup().values("name")
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • Thank you very much ! I thought about counting but could not figure out how to write such query ! It looks very promising for what I am planning to do ! Last thing, do you see any reason not to do such query, performance wise ? – Louis F. Oct 15 '16 at 15:22
  • Pretty much depends on your graph. If there are users with lots of friends (thousands+) or lots of likes, then you probably won't be able to get real-time results. However, in this case you can pre-calculate shortcut edges, but that's another topic. – Daniel Kuppitz Oct 15 '16 at 17:49