基本查询

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

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

创建数据模型

在创建属性图数据库之前,务必开发合适的数据模型。这将为数据提供结构,并允许图的用户有效地检索他们正在寻找的信息。

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

introduction schema

它包括两种类型的节点标签

  • Person 节点,具有以下属性:nameborn

  • Movie 节点,具有以下属性:titlereleasedtagline

数据模型还包含 PersonMovie 节点之间的五种不同关系类型:ACTED_INDIRECTEDPRODUCEDWROTEREVIEWED。两种关系类型具有属性

  • ACTED_IN 关系类型,具有 roles 属性。

  • REVIEWED 关系类型,具有 summary 属性和 rating 属性。

要详细了解图数据库的数据建模,请报名参加 GraphAcademy 提供的免费 图数据建模基础 课程。

创建属性图数据库

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

查找节点

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

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

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

"Keanu Reeves"

1964

1964

行数:1

查询
MATCH (people:Person)
RETURN people
LIMIT 5
也可以查询图以查找多个节点。此查询匹配所有具有 Person 标签的节点,并将结果限制为仅包含五行。
表 2. 结果

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 (bornInEighties:Person)
WHERE bornInEighties.born >= 1980 AND bornInEighties.born < 1990
RETURN bornInEighties.name as name, bornInEighties.born as born
ORDER BY born DESC
在以下示例中,第一个 MATCH 子句查找所有具有 Person 标签的节点。然后,第二个子句将过滤这些节点,以查找所有在 1980 年代出生的 Person 节点。最后一个子句按降序时间顺序返回结果。
name born

表 3. 结果

1985

"Emile Hirsch"

1982

"Rain"

1981

"Natalie Portman"

1980

"Christina Ricci"

行数:4

有关更多详细信息,请参阅有关 子句组合 的部分。

查找连接的节点

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

查询
MATCH (m:Movie {title: 'The Matrix'})<-[d:DIRECTED]-(p:Person)
RETURN p.name as director
例如,以下查询匹配图以查找电影“黑客帝国”的导演,并返回其导演的 name 属性。
表 4. 结果

director

"Lilly Wachowski"

"Lana Wachowski"

行数:2

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

也可以查找连接节点的关系类型。以下查询搜索图以查找从 Tom Hanks 节点到任何 Movie 节点的传出关系,并返回关系以及连接到他的电影的标题。

introduction example1
结果显示他具有 13 个传出关系连接到 12 个不同的 Movie 节点(12 个具有 ACTED_IN 类型,一个具有 DIRECTED 类型)。
表 5. 结果 type

movie

"ACTED_IN"

movie

"Apollo 13"

movie

"You’ve Got Mail"

movie

"A League of Their Own"

movie

"That Thing You Do"

movie

"The Da Vinci Code"

movie

"Cloud Atlas"

movie

"Joe versus the Volcano"

movie

"Cast Away"

movie

"The Green Mile"

movie

"Sleepless in Seattle"

movie

"The Polar Express"

"Charlie Wilson’s War"

"A League of Their Own"

"DIRECTED"

行数:13

查询
MATCH (:Person {name:'Tom Hanks'})-[r:!ACTED_IN]->(m:Movie)
Return type(r) AS type, m.title AS movies
可以通过向子句中添加标签表达式来进一步修改 Cypher 查询。例如,以下查询使用 NOT 标签表达式 (!) 返回连接到 Tom Hanks 的所有关系,但类型不为 ACTED_IN
表 5. 结果 type

"Charlie Wilson’s War"

"A League of Their Own"

1964

有关 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
表 7. 结果
name bornIn

"Mike Nichols"

1931

"Ian McKellen"

1939

"James Cromwell"

1940

"Nora Ephron"

1941

"Penny Marshall"

1943

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

也可以匹配图以查找可变长度的模式。以下查询匹配距离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
表 8. 结果
name bornIn

"Max von Sydow"

1929

"Clint Eastwood"

1930

"Gene Hackman"

1930

"Richard Harris"

1930

"Mike Nichols"

1931

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

上面两个示例中使用的量词是在 Neo4j 5.9 中发布的量化路径模式中引入的。在此之前,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 条不同的路径在最短长度方面并列。

表 9. 结果
pathCount pathLength

2

4

1964

SHORTEST关键字是在 Neo4j 5.21 中引入的,它在功能上替代并扩展了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
表 10. 结果
recommended strength

"Tom Hanks"

4

"John Hurt"

3

"Jim Broadbent"

3

"Halle Berry"

3

"Stephen Rea"

3

"Rain"

3

"Ben Miles"

3

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

在电影数据库中,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
表 11. 结果
coActor

"Charlize Theron"

"Hugo Weaving"

"Lana Wachowski"

删除图

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

MATCH (n)
DETACH DELETE n

有关更多信息,请参阅有关DELETE子句的部分。