基本查询

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

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

创建数据模型

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

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

introduction schema

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

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

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

该数据模型还包含 Person 节点和 Movie 节点之间的五种不同关系类型: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. 结果
姓名 出生年份

"Keanu Reeves"

1964

行数:1

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

查询
MATCH (people:Person)
RETURN people
LIMIT 5
表 2. 结果
人物

{"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
表 3. 结果
姓名 出生年份

"Emile Hirsch"

1985

"Rain"

1982

"Natalie Portman"

1981

"Christina Ricci"

1980

行数:4

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

查找连接的节点

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

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

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

"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 类型)。

introduction example1
表 5. 结果
类型 电影

"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
表 6. 结果
类型 电影

"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
表 7. 结果
姓名 bornIn

"Mike Nichols"

1931

"Ian McKellen"

1939

"James Cromwell"

1940

"Nora Ephron"

1941

"Penny Marshall"

1943

行数:5

还可以匹配可变长度的图模式。以下查询匹配距离 Tom Hanks 1 到 4 跳的所有 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. 结果
姓名 bornIn

"Max von Sydow"

1929

"Clint Eastwood"

1930

"Gene Hackman"

1930

"Richard Harris"

1930

"Mike Nichols"

1931

行数:5

上述两个示例中使用的量词是在 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. 结果
路径数量 路径长度

2

4

行数:1

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

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

查找推荐

Cypher 允许更复杂的查询。以下查询试图为 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. 结果
推荐 强度

"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
表 11. 结果
合作演员

"Charlize Theron"

"Hugo Weaving"

行数:2

删除图

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

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