文章目录
查看官网文档
基本概念
从根本上讲,Neo4j图数据库由三个核心实体组成:节点、关系和路径。Cypher查询被构造为在图中匹配或创建这些实体。因此,基本了解图数据库中的节点、关系和路径对于构建Cypher查询至关重要。
Cypher
Cypher是与Neo4j图数据库进行交互的语言。
Node(节点)
- Neo4j图数据库中的数据实体称为节点。节点信息包含标签(Label)和属性(Property)。标签的作用是将(在某方面)相似的节点归类,可以打单个、多个标签,也可以不打标签。Neo4j的数据类型有BOOLEAN, DATE, DURATION, FLOAT, INTEGER, LIST, LOCAL DATETIME, LOCAL TIME, POINT, STRING, ZONED DATETIME, and ZONED TIME。更多
- 在Cypher里节点的格式为(:标签{JSON格式填写属性})。标签非必须,可以没有({JSON格式填写属性}),也可以有一个或多个(:标签1:标签2{JSON格式填写属性})。
Relationship(关系)
- 图中的节点可以通过关系进行连接。一个关系必须有一个开始节点、一个结束节点,且有且仅有一种类型(Type)。关系可以有属性(Property),也可以没有。
- 注:两节点之间可以没有关系,也可以有一种、多种关系
- 注:节点也可以与自身建立关系
- 在Cypher里关系的格式为-[:类型{JSON格式填写属性}]->,箭头方向即关系的方向。对比节点,节点用()表示,关系用[]加箭头表示。
Path(路径)
图中的路径由连接的节点和关系组成。探索这些路径是Cypher的核心。
简单示例
完成Neo4j的安装后,浏览器访问http://localhost:7474。第一次登录时用户名密码默认都是neo4j,第一次登录后会要求改密码。下面进行一个简单示例。
- 需求:将韦小宝、康熙和建宁公主的数据存入Neo4j图数据库中。
- 韦小宝:男,18岁,即是朝廷的人也是天地会的人
- 康熙:男,19岁,朝廷的人
- 建宁公主:女,16岁,朝廷的人
- 韦小宝 ⟶ (的)朋友(是) 康熙 韦小宝 \stackrel{(的)朋友(是)}{\longrightarrow} 康熙 韦小宝⟶(的)朋友(是)康熙
- 韦小宝 ⟶ (的)上司(是) 康熙 韦小宝 \stackrel{(的)上司(是)}{\longrightarrow} 康熙 韦小宝⟶(的)上司(是)康熙
- 康熙 ⟶ (的)妹妹(是) 建宁公主 康熙 \stackrel{(的)妹妹(是)}{\longrightarrow} 建宁公主 康熙⟶(的)妹妹(是)建宁公主
- 韦小宝 ⟶ (的)老婆(之一是) 建宁公主,从小说第 45 回开始 韦小宝 \stackrel{(的)老婆(之一是)}{\longrightarrow} 建宁公主,从小说第45回开始 韦小宝⟶(的)老婆(之一是)建宁公主,从小说第45回开始
- 分析:新增3个节点用来存放韦小宝、康熙和建宁公主的信息,每个节点有3个属性,姓名name为文本型数据,性别isMale为布尔型数据,年龄age为整数型数据,根据各人身份打上标签。新增4条关系,其中最后一条关系有属性since=45。
- 操作:
-
新增节点(n1、n2、n3为临时变量名,方便后面的RETURN返回;如果只需要新增记录不需要查看结果,可不写;CREATE(节点1:标签{JSON格式填写属性}),({可不写变量名也不打标签只JSON填写属性,注意JSON外面需要小括号括起来,Neo4j里用小括号括起节点}))
CREATE (n1:朝廷:天地会{name:'韦小宝',isMale:true,age:18}), (n2:朝廷{name:'康熙',isMale:true,age:19}), (n3:朝廷{name:'建宁公主',isMale:false,age:16}) RETURN n1,n2,n3;
-
新增关系(先用MATCH语句找到节点,再给节点新增关系;这里采用的是新增节点后再新增关系的方式,也可以在新增节点的同时把关系连好CREATE (n1)-[:类型]->(n2)<-[:类型]-(n3))
MATCH (n1{name: '韦小宝'}), (n2 {name: '康熙'}), (n3 {name: '建宁公主'}) CREATE (n1)-[:朋友]->(n2)-[:妹妹]->(n3), (n1)-[:上司]->(n2), (n1)-[:老婆{since:45}]->(n3) RETURN n1,n2,n3;
- 这里有个黄色警告(TODO)
- 这里有个黄色警告(TODO)
-
CRUD
增CREATE
新增节点
- 新增节点:CREATE (:标签{JSON格式的属性})
- 新增节点不带标签:CREATE ({JSON格式的属性})
- 新增节点带多个标签,用英文冒号分割:CREATE (:标签1:标签2{JSON格式的属性})
- 新增多个节点,用英文逗号分隔:CREATE (:标签{JSON格式的属性}),(…),(…)
-
示例
-- RETURN子句方便查看操作结果,不需要可不写 CREATE (n1:朝廷:天地会{name:'韦小宝',isMale:true,age:18}), (n2:朝廷{name:'康熙',isMale:true,age:19}), (n3:朝廷{name:'建宁公主',isMale:false,age:16}) RETURN n1,n2,n3;
-
新增关系
-
已存在节点,需先找到节点再连上关系。关系必须有类型,且只能有一种类型;两节点之间可以没有关系,也可以有一种、多种关系;节点也可以与自身建立关系:
MATCH (n1查询条件), (n2查询条件2))
CREATE (n1)-[:关系类型{JSON格式的属性}]->(n2)- 示例
MATCH (n1{name: '韦小宝'}), (n2 {name: '康熙'}), (n3 {name: '建宁公主'}) CREATE (n1)-[:朋友]->(n2)-[:妹妹]->(n3), (n1)-[:上司]->(n2), (n1)-[:老婆{since:45}]->(n3) RETURN n1,n2,n3;
- 示例
-
不存在节点,可在新增节点时就连上关系:
CREATE (n1:标签{JSON格式的属性})-[r12:关系类型{JSON格式的属性}]->(n2:标签{JSON格式的属性})<-[r23:关系类型{JSON格式的属性}]-(n3:标签{JSON格式的属性})
删DELETE、REMOVE
DELETE用于删除节点和关系。REMOVE用于删除节点和关系的属性,以及节点的标签。在不删除关系的情况下,无法删除与其连接了关系的节点。这可以通过显式删除特定关系或使用DETACH DELETE子句来完成,DETACH是分离的意思,即分离并删除节点。
- 删除节点:
MATCH(n查询条件)
DELETE n- 若节点n有关系连着,则会显示删不掉,可先将该节点的全部关系删除再删该节点,或使用DETACH DELETE子句:
MATCH(n查询条件)
DETACH DELETE n- 删除全部节点:
MATCH (n)
DETACH DELETE n
- 删除全部节点:
- 若节点n有关系连着,则会显示删不掉,可先将该节点的全部关系删除再删该节点,或使用DETACH DELETE子句:
- 删除关系:
- 删除n1和n2之间的所有关系:
MATCH (n1查询条件)-[r]->(n2查询条件)
DELETE r- 删除全部关系:
MATCH ()-[r]->()
DELETE r
- 删除全部关系:
- 指定删除n1和n2之间的某条关系,只需要将r的查询条件加上即可:
MATCH (n1查询条件)-[r查询条件]->(n2查询条件)
DELETE r- 示例
MATCH (n1{name: '韦小宝'})-[r:朋友]->(n2 {name: '康熙'}) DELETE r RETURN n1,n2;
- 示例
- 删除n1和n2之间的所有关系:
- 删除节点和关系的属性:
- 删除节点的属性:
MATCH(n查询条件)
REMOVE n.某属性- 删除节点的全部属性:SET n={}
- 删除关系的属性:
MATCH (n1查询条件)-[r]->(n2查询条件)
REMOVE r.某属性- 删除关系的全部属性:SET r={}
- 删除节点的属性:
- 删除节点的标签:(多个标签的话用英文冒号分割)
MATCH(n查询条件)
REMOVE n:标签1:标签2- 删除节点的全部标签:(度娘给的建议是别这样做)
改SET
SET子句用于更新节点和关系的属性,以及节点的标签。
- 属性:根据查询条件找到节点和关系,SET 它.属性1=属性值1,它的属性2=属性值2
- 标签:根据查询条件找到节点,SET 它:标签1:标签2
查MATCH、OPTIONAL MATCH、WITH、WHERE
MATCH和OPTIONAL MATCH
查节点:MATCH (n:标签{属性:属性值})
-
注:根据标签查询时可使用与(&)、或(|)、非(!)
- 示例
MATCH (n:天地会&朝廷) RETURN n;
- 示例
MATCH (n:!天地会) RETURN n;
- 示例
-
注:根据属性查询时,只能根据是否等于该属性值作为查询依据,如果想用更复杂的表达式,需要接WHERE子句。WHERE本身并不是子句,它必须是MATCH、OPTIONAL MATCH或WITH子句的一部分。
- 示例
MATCH (n{age:18}) RETURN n;
- 示例
# MATCH (n:{age>=18})会报错 MATCH (n) WHERE n.age>=18 RETURN n;
- 示例
查关系:查关系时可指明关系的方向–>或<–,也可不指明–;如果需要指明关系的类型,在两短横线间增加[:类型],查询时关系的类型也支持与或非(参考根据标签查节点);如果需要指明关系的属性[{属性:属性值}]
- 示例
-- 跟韦小宝有关系的人 MATCH (n1{name:'韦小宝'})--(n2) RETURN n2;
- 示例
-- 韦小宝的老婆是 MATCH (n1{name:'韦小宝'})-[:老婆]->(n2) RETURN n2;
上面的MATCH也可以用OPTIONAL MATCH替代,两者的区别是:MATCH在查询不到结果时,返回空集,OPTIONAL MATCH会返回用null作为填充值的集合。应该用MATCH来查找模式中必须存在的实体,OPTIONAL MATCH用于查找模式中可能不存在的实体。
WITH(TODO)
WITH允许将查询部分链接在一起,将一个查询部分的结果管道化,用作下一个查询的起点或条件。
- 表达式
WHERE
WHERE本身并不是子句,它必须是MATCH、OPTIONAL MATCH或WITH子句的一部分。
-
比较:>、=、<、>=、<=、<>(不等于)
-
布尔操作:AND、OR、XOR、NOT
- NOT
示例MATCH (n:Person) WHERE NOT n.name ENDS WITH 'y' RETURN n.name, n.age
- NOT
-
动态计算:(有机会用到再研究)更多
-
IS NULL、IS NOT NULL
-
文本类匹配,用于String类型的数据
- START WITH
- END WITH
- CONTAINS
- IS NORMALIZED(有机会用到再研究)更多
-
正则表达式(格式为=~‘正则表达式’,注意有时需要转义字符)
-
IN
示例MATCH (a:Person) WHERE a.name IN ['Peter', 'Timothy'] RETURN a.name, a.age
返回数据RETURN
-
任何表达式都可以作为返回项
-
返回节点/关系的属性用.表示:RETURN n.name
-
返回节点的标签用labels()表示:RETURN labels(变量)
-
返回关系的类型用type()表示:RETURN type(变量)
-
返回路径:
MATCH p=(:Person)-[:OWNS]->(:Car)
RETURN p AS path -
RETURN *表示返回所有查到的数据
-
返回的数据可以用别名来存放,方便进行接下来的一些操作:RETURN n.name AS carOwners
-
去重:RETURN DISTINCT n
-
排序(默认正序):RETURN n ORDER BY n.age
- 倒序:RETURN n ORDER BY n.age DESC
-
返回前多少条数据:RETURN n LIMIT 10
-
返回的数据跳过前多少条:RETURN n SKIP 10
-
统计返回的数据有多少条:RETURN count(*)
-
标签表达式:返回表达式的判断结果(真/假)的列表
MATCH (n)
RETURN n:A&B
-
关系类型表达式:返回表达式的判断结果(真/假)的列表
MATCH (n:Label)-[r]->(m:Label)
RETURN r:R1|R2 AS result -
多个返回数据的并集:UNION ALL包含重复项,可通过去掉ALL(即UNION)达到并集且去重的效果。
示例MATCH (n:Actor) RETURN n.name AS name UNION ALL MATCH (n:Movie) RETURN n.title AS name
MERGE(TODO)
MERGE子句要么匹配图中的现有节点模式并绑定它们,要么(如果不存在)创建新数据并绑定它们。MERGE是并入的意思。
- MERGE替代CREATE实现没有则创建的功能
UNWIND
UNWIND子句可以将任何列表转换回单独的行。这些列表可以是传入的参数、以前收集的结果或其他列表表达式。
UNWIND条款的常见用法:
创建唯一列表。
从提供给查询的参数列表中创建数据。
- 示例
- 示例
- 示例
FOREACH
遍历操作。
- 示例
MATCH (n:Person) WHERE NOT n.name ENDS WITH 'y' RETURN n.name, n.age
批量导入
Neo4j是通过CSV文件进行批量导入的,文件可以在本地也可以在远程地址。
-
示例
step1.创建artists.csv文件,并将其放在Neo4j安装目录下的import文件夹1,ABBA,1992 2,Roxette,1986 3,Europe,1979 4,The Cardigans,1992
step2.通过LOAD CSV语句进行批量导入
LOAD CSV FROM 'file:///artists.csv' AS row MERGE (n:Artist {name: row[1], year: toInteger(row[2])}) RETURN n.name, n.year
- 注:本示例从本地获取CSV文件,远程的话只需要改FROM后接的语句即可,如’https://data.neo4j.com/bands/artists.csv’、'ftp://:@/bands/artists.csv’等。