Cypher查询找到" best"将汤姆汉克斯介绍给汤姆克鲁斯的人

时间:2016-10-17 17:54:31

标签: neo4j cypher

我正在浏览neo4j 3.0.6电影图示例,我正处于"找人向汤姆克鲁斯介绍汤姆汉克斯的部分。" 执行后

MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
      (coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cruise:Person {name:"Tom Cruise"})
RETURN tom, m, coActors, m2, cruise

我得到以下图表: enter image description here

根据那些与汤姆·汉克斯和汤姆·克鲁斯关系最密切的人,Cypher的查询对联合演员的排名是什么?结果看起来类似于:

Name        , connecting_movies, (OR) connecting_edges
Meg Ryan    , 4                , 8
Bonnie Hunt , 2                , 4
Kevin Bacon , 2                , 4

2 个答案:

答案 0 :(得分:1)

由于你只看一种关系类型(:ACTED_IN),所以应该使用普通电影的数量并省去边缘(边缘将是2倍数量的电影,除非其中一个演员播放多个同一部电影中的角色,但这似乎不是对更强连接的有意义的衡量标准。)

然而,我们必须确保在计算时只考虑不同的电影,因为可能会有一部电影,其中所有参与者都扮演了角色(Tom,Tom和coactor),我们只想要把电影算一次,而不是两次。为了确保我们获得不同的计数,我们需要将两列电影(m和m2)合并为一列,然后在该列中获得不同的电影数量。

不幸的是,此时Neo4j的UNION将不允许我们继续处理联合结果(获得计数),因此我们必须将每列电影转换为集合,将集合添加到一起,然后将单个集合展开到一列电影中。最终查询如下所示:

MATCH (:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors)
MATCH (coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(:Person {name:"Tom Cruise"})
WITH coActors, collect(m) + collect(m2) as allMovies
UNWIND allMovies as moviesInCommon
RETURN coActors, COUNT(DISTINCT moviesInCommon) as commonMoviesCnt
ORDER BY commonMoviesCnt DESC
编辑我将你的第一个MATCH改为两个MATCH,因为在单个匹配行中,m中的电影在m2中不匹配(我鼓励你将描述中的查询更改为2个匹配)。虽然这会给我们带来不同的数量(我们想要的东西),但它也会阻止我们正确地匹配在同一部电影中与两个感兴趣的演员一起行动的合作者。

您可以通过将您感兴趣的人改为Tom Hanks和Meg Ryan来测试。当然,他们已经相互了解,不需要介绍,但使用这两个可以更好地显示当两个演员在同一部电影中合作时哪些查询正常工作。

答案 1 :(得分:1)

[增订]

您的单个​​public static void main(String[] args) { SammysContract contracts = new SammysContract(); contracts.printWelcome(); contracts.inputContract(); contracts.rentalItem(); contracts.hourID(); contracts.minuteID(); contracts.calculateCost(); } 子句强制MATCHm计数始终相同,这意味着对于特定m2 coActor或{{ 1}}节点可以多次出现。为避免这种重复,您可以将其拆分为2个m子句并单独获取计数,如下所示。此查询还会过滤掉Toms所执行的电影,因为这意味着不再需要引入这些电影。

m2