Получить всех актеров, сыгравших в фильме, который понравился всем моим друзьям

#titan #tinkerpop #tinkerpop3

#titan #тинкерпоп #тинкерпоп3

Вопрос:

Я играю с TinkerPop, и у меня в голове застряла эта проблема: я хотел бы найти всех актеров из фильмов, которые понравились ВСЕМ моим друзьям (другими словами, найдите общие фильмы, которые понравились моим друзьям, и получите имена всех актеров, которые играли в этих фильмах)

до сих пор то, что я пробовал :

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

возвращает всех актеров, сыгравших в фильме, который понравился хотя бы ОДНОМУ из моих друзей. Я совсем новичок в TinkerPop, и обширный API меня почему-то смущает.

Спасибо!

Ответ №1:

Как всегда, давайте начнем с примера графика:

 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()
 

Как вы уже можете видеть, only movie 2 понравился всем друзьям user 1 . Ниже приведен обход для ответа на вопрос (со встроенными комментариями).:

 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]
 

Теперь, если вы хотите получить имена актеров, вам нужно только добавить:

 .in("play_in").dedup().values("name")
 

Комментарии:

1. Большое вам спасибо ! Я думал о подсчете, но не мог понять, как написать такой запрос! Это выглядит очень многообещающе для того , что я планирую сделать ! И последнее, видите ли вы какие-либо причины не выполнять такой запрос с точки зрения производительности?

2. В значительной степени это зависит от вашего графика. Если есть пользователи с большим количеством друзей (более тысячи) или большим количеством лайков, то вы, вероятно, не сможете получать результаты в режиме реального времени. Однако в этом случае вы можете предварительно рассчитать края ярлыка, но это уже другая тема.