基础查询

本页面包含有关如何使用 Cypher® 创建、查询和删除图数据库的信息。如需了解更高级的查询,请参阅子查询章节。

以下示例使用了公开可用的 Neo4j 电影数据库

创建数据模型

在创建属性图数据库之前,制定一个合适的数据模型非常重要。这将为数据提供结构,并允许图数据库用户高效地检索他们所需的信息。

Neo4j 数据模型使用以下数据模型

它包含两种节点标签

  • Person(人物)节点,具有以下属性:name(姓名)和 born(出生年份)。

  • Movie(电影)节点,具有以下属性:title(标题)、released(上映年份)和 tagline(标语)。

该数据模型还包含 PersonMovie 节点之间的五种不同关系类型:ACTED_IN(参演)、DIRECTED(导演)、PRODUCED(制片)、WROTE(编剧)和 REVIEWED(评论)。其中两种关系类型具有属性

  • ACTED_IN 关系类型,具有 roles(角色)属性。

  • REVIEWED 关系类型,具有 summary(摘要)属性和 rating(评分)属性。

要了解更多关于图数据库数据建模的信息,请注册 GraphAcademy 提供的免费课程:图数据建模基础 (Graph Data Modelling Fundamentals)

创建属性图数据库

用于创建 Neo4j 电影数据库的完整 Cypher 查询可以在这里找到。要创建完整的图,请针对一个空的 Neo4j 数据库运行此完整查询。

查找节点

MATCH 子句用于在图中查找特定的模式,例如特定节点。RETURN 子句指定返回所找到图模式中的哪些部分。

例如,此查询将查找标签为 Person 且名称为 Keanu Reeves 的节点,并返回所找到节点的 nameborn 属性

查询
MATCH (keanu:Person {name:'Keanu Reeves'})
RETURN keanu.name AS name, keanu.born AS born
结果
名称 (name) born

"Keanu Reeves"

1964

行:1

也可以查询图中的多个节点。此查询匹配所有带有 Person 标签的节点,并将结果限制为仅包含五行。

查询
MATCH (people:Person)
RETURN people
LIMIT 5
结果
people

{"born":1964,"name":"Keanu Reeves"}

{"born":1967,"name":"Carrie-Anne Moss"}

{"born":1961,"name":"Laurence Fishburne"}

{"born":1960,"name":"Hugo Weaving"}

{"born":1967,"name":"Lilly Wachowski"}

行:5

关于子句组合的说明

与 SQL 类似,Cypher 查询是通过连接各种子句来构建的,这些子句将中间结果在彼此之间进行传递。每个子句的输入都是图的状态和一个由引用变量组成的中间结果表。第一个子句的输入是查询前的图状态和一张空的中间结果表。子句的输出是新的图状态和一张新的中间结果表,作为下一个子句的输入。最后一个子句的输出即为查询结果。

请注意,如果其中一个子句返回空的中间结果表,则没有数据可传递给后续子句,从而结束查询。(可以通过某些方式绕过此行为。例如,使用 OPTIONAL MATCH 替换 MATCH 子句。)

在下例中,第一个 MATCH 子句查找所有带 Person 标签的节点。第二个子句随后会过滤这些节点,以查找所有出生于 20 世纪 80 年代的 Person 节点。最后一个子句按时间倒序返回结果。

查询
MATCH (bornInEighties:Person)
WHERE bornInEighties.born >= 1980 AND bornInEighties.born < 1990
RETURN bornInEighties.name as name, bornInEighties.born as born
ORDER BY born DESC
结果
名称 (name) born

"Emile Hirsch"

1985

"Rain"

1982

"Natalie Portman"

1981

"Christina Ricci"

1980

行:4

有关更多详细信息,请参阅子句组合章节。

查找连接的节点

要了解节点之间是如何连接的,必须将关系添加到查询中。查询可以指定关系类型、属性和方向,以及模式的起始节点和结束节点。

例如,以下查询在图中匹配电影《黑客帝国》(The Matrix) 的导演,并返回其导演的 name 属性。

查询
MATCH (m:Movie {title: 'The Matrix'})<-[d:DIRECTED]-(p:Person)
RETURN p.name as director
结果
director

"Lilly Wachowski"

"Lana Wachowski"

行:2

还可以查找连接节点之间的关系类型。下方的查询在图中搜索从 Tom Hanks 节点发出的指向任何 Movie 节点的出站关系,并返回这些关系以及与他连接的电影标题。

查询
MATCH (tom:Person {name:'Tom Hanks'})-[r]->(m:Movie)
RETURN type(r) AS type, m.title AS movie

结果显示他有 13 个出站关系连接到 12 个不同的 Movie 节点(其中 12 个是 ACTED_IN 类型,1 个是 DIRECTED 类型)。

结果
type movie

"ACTED_IN"

"Apollo 13"

"ACTED_IN"

"You’ve Got Mail"

"ACTED_IN"

"A League of Their Own"

"ACTED_IN"

"That Thing You Do"

"ACTED_IN"

"The Da Vinci Code"

"ACTED_IN"

"Cloud Atlas"

"ACTED_IN"

"Joe versus the Volcano"

"ACTED_IN"

"Cast Away"

"ACTED_IN"

"The Green Mile"

"ACTED_IN"

"Sleepless in Seattle"

"ACTED_IN"

"The Polar Express"

"ACTED_IN"

"Charlie Wilson’s War"

"DIRECTED"

"That Thing You Do"

行数: 13

通过向子句添加标签表达式,可以进一步修改 Cypher 查询。例如,下方的查询使用 NOT 标签表达式 (!) 来返回所有与 Tom Hanks 相连且非 ACTED_IN 类型的关系。

查询
MATCH (:Person {name:'Tom Hanks'})-[r:!ACTED_IN]->(m:Movie)
Return type(r) AS type, m.title AS movies
结果
type movie

"DIRECTED"

"That Thing You Do"

行:1

有关 Cypher 支持的不同标签表达式的更多信息,请参阅标签表达式章节。

查找路径

Cypher 有多种方式可用于在图中搜索节点之间的路径。

要搜索固定长度的模式,可以使用量词 ({n}) 指定模式中节点之间的距离(跳数)。例如,以下查询匹配所有距离 Tom Hanks 恰好 2 跳的 Person 节点,并返回前五行结果。DISTINCT 运算符确保结果中不包含重复值。

查询
MATCH (tom:Person {name:'Tom Hanks'})--{2}(colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn
LIMIT 5
结果
名称 (name) bornIn

"Mike Nichols"

1931

"Ian McKellen"

1939

"James Cromwell"

1940

"Nora Ephron"

1941

"Penny Marshall"

1943

行:5

也可以匹配图中变长模式。下方的查询匹配所有距离 Tom Hanks 之间为 14 跳的 Person 节点,并返回前五行结果。

查询
MATCH (p:Person {name:'Tom Hanks'})--{1,4}(colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn, name
LIMIT 5
结果
名称 (name) bornIn

"Max von Sydow"

1929

"Clint Eastwood"

1930

"Gene Hackman"

1930

"Richard Harris"

1930

"Mike Nichols"

1931

行:5

上述两个示例中使用的量词是随量化路径模式的发布而引入的。在此之前,Cypher 中匹配变长路径的唯一方法是使用变长关系。这种语法在 Cypher 中仍然可用,但它不符合 GQL 标准。有关更多信息,请参阅 模式 → 语法与语义 → 变长关系

SHORTEST 关键字可用于查找两个节点之间最短路径的变体。在此示例中,查找了 Keanu ReevesTom Cruise 两个节点之间的 ALL SHORTEST(所有最短)路径。count() 函数计算这些最短路径的数量,而 length() 函数以经过的关系数量计算每条路径的长度。

查询
MATCH p = ALL SHORTEST (:Person {name:"Keanu Reeves"})--+(:Person {name:"Tom Cruise"})
RETURN count(p) AS pathCount, length(p) AS pathLength

结果显示有 2 条不同的路径并列最短。

结果
pathCount 路径长度

2

4

行:1

SHORTEST 关键字在功能上替代并扩展了 shortestPath()allShortestPaths() 函数。这两个函数仍然可以使用,但它们不符合 GQL 标准。有关更多信息,请参阅 模式 → 语法与语义 → shortestPath()allShortestPaths() 函数

有关图模式匹配的更多信息,请参阅模式

查找推荐

Cypher 允许执行更复杂的查询。以下查询试图为 Keanu Reeves 推荐他尚未合作过、但他的合作演员曾与之合作过的演员。查询随后会根据匹配到的演员与 Keanu Reeves 的合作演员之间的合作频率对结果进行排序。

查询
MATCH (keanu:Person {name:'Keanu Reeves'})-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(coActors:Person),
  (coActors:Person)-[:ACTED_IN]->(m2:Movie)<-[:ACTED_IN]-(cocoActors:Person)
WHERE NOT (keanu)-[:ACTED_IN]->()<-[:ACTED_IN]-(cocoActors) AND keanu <> cocoActors
RETURN cocoActors.name AS recommended, count(cocoActors) AS strength
ORDER BY strength DESC
LIMIT 7
结果
recommended strength

"Tom Hanks"

4

"John Hurt"

3

"Jim Broadbent"

3

"Halle Berry"

3

"Stephen Rea"

3

"Natalie Portman"

3

"Ben Miles"

3

行:5

虽然电影数据库中 Keanu ReevesTom Hanks 节点之间存在多种连接,但两人从未在同一部电影中合作过。以下查询通过寻找曾分别与他们两人在不同电影中合作过的演员,来匹配可以为他们进行介绍的合作演员。

查询
MATCH (:Person {name: 'Keanu Reeves'})-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(coActor:Person),
  (coActor)-[:ACTED_IN]->(:Movie)<-[:ACTED_IN]-(:Person {name:'Tom Hanks'})
RETURN DISTINCT coActor.name AS coActor
结果
coActor

"Charlize Theron"

"Hugo Weaving"

行:2

删除图

要删除图中的所有节点和关系,请运行以下查询

MATCH (n)
DETACH DELETE n
DETACH DELETE 不适用于删除大量数据,也不会删除图的索引模式。有关更多信息以及 DETACH DELETE 的替代方案,请参阅 DELETE → 删除所有节点和关系