Neo4J包含所有查询

时间:2016-03-23 19:06:58

标签: neo4j cypher

我是neo4j和图形数据库的新手。

我试图创建一个我称之为“包含全部”的查询。但是我觉得我离我很远,不知道如何进步

MATCH (movie:Movie {name:'tropic thunder'})-[:stars_in]-(actors)
      -[:guest_stars_in]-(movie2)
RETURN movie2.name

让我们说吧 MATCH (movie:Movie{name:'tropic thunder'})-[:stars_in]-(actors) 返回5个演员

我希望完全匹配(所有5个演员 - >相同的5个演员作为客串明星)或作为一个子集(所有5个演员都是拥有10个客串明星的电影的子集)。

希望这是有道理的。谢谢你的帮助:D

1 个答案:

答案 0 :(得分:1)

我要指出的第一件事是你应该调用变量actor而不是actors。它可能看起来很挑剔,但它与Cypher的共同混淆。使用MATCH,您一次匹配一个子模式。

首先,让我们找到每个movie2并获得一个有问题的演员阵列:

MATCH (movie:Movie {name:'tropic thunder'})-[:stars_in]-(actor)
      -[:guest_stars_in]-(movie2)
RETURN movie2.name, collect(actor)

第一直觉可能是像这样扩展路径:

MATCH (movie:Movie {name:'tropic thunder'})-[:stars_in]-(actor)
      -[:guest_stars_in]-(movie2)-[:guest_starts_in]-(actor2)

但是,我们再次匹配数据库中该路径的每个可能匹配项。因此,对于每个actor,我们将匹配所有可能的actor2,这将导致重复。

但我们可以做的是接受我们的第一个查询并将RETURN更改为WITH,以便将我们的数据传递到查询的第二部分:

MATCH (movie:Movie {name:'tropic thunder'})-[:stars_in]-(actor)
      -[:guest_stars_in]-(movie2)
WITH movie2, collect(actor) AS original_movie_actors
MATCH movie2-[:guest_stars_in]-(guest_star)
RETURN movie2.name, original_movie_actors, collect(guest_star) AS guest_stars

这给了我们

  • 有问题的电影列表
  • 那些盯着“热带风头”并且客人盯着有问题的电影的演员名单
  • 有问题的电影的所有客串明星

从这里你可以用你选择的编程语言来解决它。但我们也可以在Cypher中解决这个问题:

MATCH (movie:Movie {name:'tropic thunder'})-[:stars_in]-(actor)
      -[:guest_stars_in]-(movie2)
WITH movie2, collect(actor) AS original_movie_actors
MATCH movie2-[:guest_stars_in]-(guest_star)
WITH movie2, original_movie_actors, collect(guest_star) AS guest_stars

RETURN
  movie.name,
  ALL(guest_star IN guest_stars WHERE guest_star IN original_movie_actors) AS all_matched,
  length(original_movie_actors) / length(guest_stars) AS percentage_match

我在percentage_match进行了一次双重检查,如果有用的话