What is Cypher? 什么是 Cypher
cypher n. 密码,暗号
Cypher is a graph query language that is used to query the Neo4j Database. Just like you use SQL to query a MySQL database, you would use Cypher to query the Neo4j Database.
Cypher 是一种图查询语言,用于查询 Neo4j 数据库。就像使用 SQL 查询 MySQL 数据库一样,您也可以使用Cypher 查询Neo4j数据库。
一个简单的 cypher 查询示例:
Match (m:Movie) where m.released > 2000 RETURN m limit 5
Nodes and Relationships 节点和关系
节点和关系是图数据库的基本结构。
Nodes 节点
节点代表实体,图数据库中的节点类似于关系数据库中的行。在下面的图片中,我们可以看到2种节点: Person 和 Movie 。在编写 cypher 查询时,节点被括在圆括号中 - 类似 (p:Person) p 是一个变量并且 Person 是它所代表的节点类型。
Relationship 关系
两个节点可以通过关系连接。在上图中 ACTED_IN, REVIEWED, PRODUCED, WROTE, DIRECTED 是连接相应类型节点的所有关系。
在编写 cypher 查询时,关系用方括号括起来,比如 [w:WORKS_FOR] ,其中 w 是一个变量并且 WORKS_FOR 是 w 所指的关系类型。两个节点可以有多个关系。
MATCH (p:Person)-[d:DIRECTED]-(m:Movie) where m.released > 2010 RETURN p,d,m
这个查询语句会返回发行日期在2010年以后的所有电影 Movie 节点以及导演 Person 节点。
Labels 标签
标签是节点或关系的名称或标识符。在下图中 Movie 和 Person 是节点标签,ACTED_IN,REVIEWED 等是关系标签。
在编写 cypher 查询时,标签以冒号作为前缀,比如 :Person
或者 :ACTED_IN
。
可以通过在冒号前加上变量名称来将节点标签分配给变量。
比如 (p:Person)
表示 p 变量 指代 Person 标记的节点。类似面向对象中变量和类的关系。
MATCH (p:Person) RETURN p limit 20
只查询 Person 类型的节点 (limiting to 20 items)
MATCH (n) RETURN n limit 20
查询任意类型的节点 (limiting to 20 items)
Properties 属性
属性是用于向节点和关系添加属性的键值对。为了查询并返回节点的指定属性可以这么写:
MATCH (m:Movie) return m.title, m.released
查询 Movie 节点,但是只返回 title 和 released 属性。
Create a Node 创建一个节点
Create 语句可用于创建新节点或关系。
Create (p:Person {name: 'John Doe'}) RETURN p
上述语句将创建一个新的具有 name 属性 'John Doe' 的 Person 节点。
通过 Match 和 Where 语句查询节点
Match 语句用于查找与特定模式匹配的节点。这是从Neo4j数据库获取数据的主要方式。
在大多数情况下,Match 用于配合特定条件缩小结果范围。
Match (p:Person {name: 'Tom Hanks'}) RETURN p
只能以这种方式进行基于基本字符串匹配的过滤 (不使用 WHERE 语句)。
为了实现更复杂的过滤,包括 > , < , Starts With , Ends With 等可以结合 WHERE 语句。
MATCH (p:Person) where p.name = "Tom Hanks" RETURN p
上述两个语句都会返回相同的结果。
关于 where 的更多内容请参考: neo4j.com/docs/cypher…
Merge Clause 合并语句
Merge 用于
- 匹配现有节点并绑定它们或
- 创建新节点并绑定它们
它是 Match 和 Create 的结合,此外,如果数据匹配或创建,还允许指定其他操作。
MERGE (p:Person {name: 'John Doe'}) ON MATCH SET p.lastLoggedInAt = timestamp() ON CREATE SET p.createdAt = timestamp() Return p
如果人员节点不存在,则上述语句将创建该节点。 如果节点已经存在,则它将设置属性 lastLoggedInAt = 当前时间戳。 如果节点不存在并且是新创建的,则它将设置属性 createdAt = 当前时间戳。
Create a Relationship 创建关系
关系连接2个节点。
MATCH (p:Person), (m:Movie) WHERE p.name = "Tom Hanks" and m.title = "Cloud Atlas" CREATE (p)-[w:WATCHED]->(m) RETURN type(w)
上述语句将创建一个 :WATCHED 关系在 Peron 和 Movie 节点之间并返回关系的类型 (即 WATCHED)。
Relationship Types 关系类型
在Neo4j中,有两种关系- incoming 和 outgoing
在上图中,Tom Hanks 节点 被称为具有 outgoing 关系,而 Cloud Atlas 节点被称为具有 incoming 关系。
关系总是有方向的。然而,你只需要注意它有用的方向。
为了表示 cypher 中的传出或传入关系,我们使用 → 或 ← 。
Example -
MATCH (p:Person)-[r:ACTED_IN]->(m:Movie) RETURN p,r,m
在上述查询中,Person 具有传出关系,而 Movie 具有传入关系。
尽管在电影数据集的情况下,关系的方向并不那么重要,即使在查询中没有指示方向,它也会返回相同的结果。
MATCH (p:Person)-[r:ACTED_IN]-(m:Movie) RETURN p,r,m
所以上面这个不是箭头的查询也会返回相同的结果。
Clean up 清理
完成实验/测试/demo后,可以删除电影数据集。
注意:
- 如果存在关系,则无法删除节点
- 一起删除节点和关系
删除所有 Movie 和 Person 节点及其关系
MATCH (n) DETACH DELETE n
确认删除结果:
MATCH (n) RETURN n
复杂查询示例
多跳查询示例:
查询和 Person Kevin Bacon 有4跳内关系的节点和关系
MATCH (bacon:Person {name:"Kevin Bacon"})-[*0..4]-(hollywood) RETURN DISTINCT hollywood
最短路径查询示例:
查询 Kevin Bacon 和 Meg Ryan 之间的最短路径
MATCH p=shortestPath( (bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"}) ) RETURN p
Extend Tom Hanks co-actors, to find co-co-actors who haven't worked with 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]->()<-[:ACTED_IN]-(cocoActors) AND tom <> cocoActors
RETURN cocoActors.name AS Recommended, count(*) AS Strength ORDER BY Strength DESC
Find someone to introduce Tom Hanks to 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