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 !
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")