电影关系图实例将电影、电影导演、演员之间的复杂网状关系作为蓝本,使用Neo4j创建三者关系的图结构,虽然实例数据规模小但结构是相对完整的。
这个实例将指导读者学习以下入门操作:
创建图数据:将电影、演员、导演等图数据导入到Neo4j数据库中
检索节点:检索特定电影和演员
查询关系:发现相关的演员和导演
查询关系路径:查询他们之间的关系路径
1.创建图数据
(1).创建电影节点
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
上面的Cypher语句使用CREATE指令创建了一个Movie节点,这个节点上带有三个属性{title:'The Matrix', released:1999, tagline:'Welcome to the Real World'},
分别表示这个电影标题:The Matrix、发布时间:1999、宣传词:Welcome to the Real World。执行后将在数据库中创建一个Move节点
(2).创建人物节点
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
上面代码使用了CREATE指令创建了一个Person节点,节点带有两个属性{name:'Keanu Reeves', born:1964}
(3).再创建其他的演员
CREATE (Carrie:Person {name:'Carrie-Anne Moss', born:1967})
CREATE (Laurence:Person {name:'Laurence Fishburne', born:1961})
CREATE (Hugo:Person {name:'Hugo Weaving', born:1960})
CREATE (LillyW:Person {name:'Lilly Wachowski', born:1967})
CREATE (LanaW:Person {name:'Lana Wachowski', born:1965})
CREATE (JoelS:Person {name:'Joel Silver', born:1952})
(4).创建演员、导演关系
CREATE
(Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
(Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
(Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
(Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
(LillyW)-[:DIRECTED]->(TheMatrix),
(LanaW)-[:DIRECTED]->(TheMatrix),
(JoelS)-[:PRODUCED]->(TheMatrix)
上面代码中除了使用CREATE指令外,还使用了箭头运算符,如(Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),这一行的意思是创建一个演员参演电影的关系,演员Keanu以角色roles:['Neo']参演ACTED_IN到电影TheMatrix中,代码的前4行都是创建演员参演电影关系的指令,第5行指令:(LillyW)-[:DIRECTED]->(TheMatrix),意思是创建导演与电影的关系,即LillyW导演了“[:DIRECTED]”电影TheMatrix,上述指令运行完后,数据库中会有以下存储形态。
通过上述创建指令把 电影关系图 实例创建完成
2.检索节点
(1).查找人员
查找名为 'Tom Hanks' 的人物
match (tom {name:"Tom Hanks"}) return tom
上面语句使用match指令查找匹配条件:{name:"Tom Hanks"}的节点,执行的结果如下图所示:
(2).查找电影节点
查找名为 'Cloud Atlas' 的电影
match (cloud {title:"Cloud Atlas"}) return cloud
(3).随机查找多个人物的名称
随机查找10个人物的名称
match (people:Person) return people.name limit 10
在本次结果中,由于只返回name属性,所以就不用图形化的形式返回了。
(4).查找多个电影
查找1900年到2000年发行的电影的名称
match (nineties:Movie)
where nineties.released > 1990 and nineties.released < 2000
return nineties.title
上面指令稍微复杂,首先匹配Movie节点,然后使用WHERE子句查询电影的released属性值大于1990并且小于2000条件的节点, 然后值返回匹配节点的title属性,返回结果如图所示:
3.查询关系
下面拓展match指令的使用
(1).查找 'Tom Hanks' 参演过的电影的名称
match (tom:Person {name:"Tom Hanks"}) - [:ACTED_IN] -> (tomHanksMovies) return tom,tomHanksMovies
上述指令首先匹配节点类型为Person、属性为{name:"Tom Hanks"}的节点,然后匹配此节点具有关系[:ACTED_IN], 并且此关系指向某个电影节点的节点,返回结果如下图
(2).查找谁导演了电影 "Cloud Atlas"
match (cloudAtlas {title: "Cloud Atlas"}) <- [:DIRECTED]-(directors)
return directors.name
(3).查找与Tom Hanks同出演过电影的人
match (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors)
return coActors.name
上面指令首先匹配节点类型为Person、属性为{name:"Tom Hanks"}的节点,然后匹配此节点通过[:ACTED_IN]关系指向的节点m,并且同时匹配某个节点coActors也通过[:ACTED_IN]关系指向的节点m,然后返回匹配节点m的name属性。返回结果如图所示
(4).查找与电影Cloud Atlas相关的所有人
match (people:Person)-[relatedTo]-(:Movie {title:"Cloud Atlas"})
return people.name, Type(relatedTo), relatedTo
上面指令首先匹配节点类型为Person的节点,然后匹配节点类型为Movie、节点属性为{title:"Cloud Atlas"}的节点, 最后匹配他们两者之间存在某种关系(无论是导演还是演员关系)的情况,然后将人名、电影的关系类型、电影的关系同时返回,返回结果如图所示:
(5).查询关系路径
或许你听说过"六度空间"理论,也就是说,世界上任何两个人,他们之间至多通过6条关系路径就可以相互联系彼此,使用Neo4j的 关系路径查询可以查找任意深度的关系路径,也就很轻松地能够实现人脉关系查询了。
查找与演员'Kevin Bacon'存在4条及以内关系的任何演员和电影
match (bacon:Person {name:"Kevin Bacon"})-[*1..4]-(hollywood)
return distinct hollywood
上面指令首先匹配节点类型为Person、属性为{name:"Kevin Bacon"}的节点,然后将关系深度限制为从1到4在进行遍历, 最后返回匹配的所有节点,返回结果如图所示:
(6).查找与演员Kevin Bacon 与 Meg Ryan 之间的最短关系路径
match p=shortestPath((bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"}))
return p
上面指令首先匹配节点类型为Person、属性为{name:"Kevin Bacon"}的节点,再匹配节点类型为Person、属性为{name:"Meg Ryan"}的节点, 两者用[*]关系操作符相连代表两者存在任意深度的关系,然后使用shortestPath方法返回两者在所有深度关系遍历路径中最短的一条,返回结果如图所示
通过结果可以看到演员Meg Ryan 与 Tom Hanks 同参演过 Joe Versus the Volcano电影,而Tom Hanks 与 Kevin Bacon 同参演过Apollo 13 电影,这就是他们两者之间的最短关系路径。
4.为Tom Hanks推荐信的合作伙伴
要为Tom Hanks推荐信的合作伙伴,一个比较好的办法就是通过认识Tom Hanks的人的人脉来寻找信的合作伙伴。 对于Tom Hanks来说,这意味着:
第一步:先找到Tom Hanks还没合作过的演员,但Tom Hanks的合作伙伴曾经与其合作过
第二步:找到一个可以向他的潜在合作者介绍Tom Hanks的人
(1).查找没有与Tom Hanks合作过的演员
match (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
(coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cocoActors)
where not (tom)-[:ACTED_IN]->(m2)
return cocoActors.name as Recommended,count(*) as Strength
order by Strength desc
(2).找人将Tom Hanks介绍给Tom Cruise
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
5.清空数据库
清空所有Person、Movie节点及其所有关系
match (a:Person),(m:Movie)
optional match (a)-[r1]-(), (m)-[r2]-()
delete a,r1,m,r2
这样操作完成后,为了查询数据是否已经被清空了,可以运行以下命令先看数据库中是否还有任何数据
match (n) return n
如果没有,就说明已经删除成功了