零、引言
图库Neo4j使用cypher语句为基本操作语言,本文总结一些关键字的使用方法
目录- 零、引言
-
一、关键词总结
- 1.1 Load csv 读取文件
- 1.2 create 创建实体或关系
- 1.3 delete 删除实体或关系
- 1.4 match 查询节点和关系
- 1.5 set 修改实体标签或属性
- 1.6 索引的创建与删除(索引是在属性上创建的,用于加速检索)
- 1.7 单条最短路径
- 1.8 多条最短路径
- 1.9 collect 将多个值转换成列表
- 1.10 unwind 将列表拆分成多个值
- 1.11 yield 依次迭代生成对象
- 1.12 merge 有关系则返回,没有则创建关系
- 1.13 optional match 可选择匹配,若匹配结果包含空,则用NULL占位
- 1.14 XXX with 字符串开头结尾匹配
- 1.15 得到边上的节点
- 1.16 得到某节点的id或key
- 1.16 split 对指定字符串用指定分隔符split
- 1.17 count 统计指定标签下节点个数
- 1.18 distinct 对返回结果去重
- 1.19 linenumber() 返回按行操作后的行号
- 1.20 USING PERIODIC COMMIT 多行语句提交
- 1.21 grant 赋权
- 1.22 apoc.periodid.iterate 并行可迭代过程 需grant赋权
- 1.23 apoc.cypher.parallel并行化操作
一、关键词总结
1.1 Load csv
读取文件
load csv with headers from 'file:///ces.csv' as line with line, linenumber()-1 as number
call apoc.create.node([line.table],{table:line.table, ziduan:line.ziduan}) yield node return number
- 行终止标识和系统有关,例如在 Unix 中是 \n,在 Windows 上是 \r\n。 如windows环境导入
LOAD CSV FROM 'file:///F:\\code\\java\\helloworld\\artists.csv' AS line
- 分隔符必须是逗号,除非用通过 FIELDTERMINATOR 特殊指定
- 如果字符串是用双引号引起来的,数据读入后会将双引号去掉
- 任何需要转义的字符都可以通过反斜线 \ 来转义
- 要访问本地(在数据库服务器上)文件,使用 file:/// 路径。除此之外,可以使用任何 HTTPS,HTTP 和 FTP 协议
- LOAD CSV导入数据, 可配合使用apoc.node.create() 动态添加单标签,多标签
- LOAD CSV是在线导入(导入数据量和效率一般), 使用neo4j-admin import 是离线导入,必须断服务
CALL apoc.export.cypher.all('export.cypher',{format:'cypher-shell'})
- 全量导入图库所有内容,全图导出到 import目录下
- 若要载入,需在命令行中执行
cat export.cypher | cypher-shell -u neo4j -p neo4j
并重启neo4j服务
1.2 create 创建实体或关系
- 最简单的创建实体和关系(不带属性)
create (n:Person)-[:LOVES]->(m:Dog)
- 创建2个或多个属性的实体
create (z:ziduan{name:"f_name",table:"dianlibiao"}) return count(*)
- 创建带属性的实体和关系
create (n:Person{name:"李四"})-[:FEAR{level:1}]->(t:Tiger{type:"东北虎"})
- 对实体间创建关系
match (n:Person{name:""王五""}), (m:Person{name:"赵六"}) create (n)-[k:KNOW]->(m) return k
1.3 delete 删除实体或关系
- 先用match查找已有实体、关系, 再用delete删除关系
match (n:Person{name:"李四"})-[f:FEAR]->(t:Tiger) delete f
- 删除所有节点中的bian关系
match(m)-[b:bian]-(n) delete b
- match查询实体,delete删除实体
match (n:Person{name:"李四"}) delete n
- 同时删除实体和关系
match(n) detach delete n
- 删除所有节点
match (n) delete n
- 删除所有节点并级联删除关系
match (n) detach delete n
- 删除Loc标签的所有结点和关系
MATCH (r:Loc) DETACH DELETE r
1.4 match 查询节点和关系
- match 查询类似与关系型数据库中的 select , 其语法结构如下:
match
(node)-[relationship]->(node)
where
(node | relationship)
return
(node | relationship)
match (n:Persion)-[:HAS_PHONE]->(p:Phone) where n.name="姓名6" return n, p limit 10
n: 表示别名,这里定义了不同实体的别名n 和 p
:HAS_PHONE 表示关系名称
() 圆括号里面表示实体 [] 方括号里面表示关系,都是英文状态下
()-[]->() 表示实体-关系-实体 该关系是有方向的,若要表示无方向的关系,则用: ()-[]-()
- 查询所有实体节点
match(n) return n
- 根据id查找实体
match (t:Tiger) where id(t)=1837 return t
match (t:Tiger) where id(t)=1837 delete t
- 多度关系查询
match (n:Persion)-[:HAS_PHONE]->(p:Phone)-[:CALL]->(p1: Persion) where n.name=“姓名6” return n, p,p1 limit 10
- 利用关系查询, 不限定实体只限定关系的查询
match p=()-[c: CALL]->() return p limit 10
- 根据实体属性匹配正则查询, 使用通配符,通配符前要加~
match (n:USERS) where n.name=~'Jack.*' return n limit 10
- 包含查询 使用关键词contains
match (n:USERS) where n.name= contains 'J' return n limit 10
- 附带属性多实体查询, 逗号隔开,注意语法
match (n:Person{name:"王五"}), (m:Person{name:"赵六"}) return n,m
- 查询多种label节点,并进行过滤
match(n) where n:标签1 or n:标签B return distinct n;
- distinct * 关键字表示返回节点不重复
- 返回非某几类标签,注意使用 not and 关键字
match(n) where not n:标签1 and not n:标签B return distinct n;
1.5 set 修改实体标签或属性
- 给实体增加标签
match (t:Tiger) where id(t)=1837 set t:A return t
本质上是给实体增加一个标签,一个实体可以有多个标签
此时该实体有两个标签A Tiger
2. 给实体增加属性
match (a:A) where id(t)=1837 set a.年龄=10 return a
- 给关系增加属性
match (n:Person)-[l:LOVE]->(:Person) set l.date="1990" return n, l | |
- 给所有节点增加标签
match(n) set n:table return n
1.6 索引的创建与删除(索引是在属性上创建的,用于加速检索)
- 创建索引 (在Person标签的name属性上创建索引)
create index on :Person(name)
- 删除索引
drop index on :Person(name)
- 创建唯一索引(在实体Person的name属性上创建唯一索引)
create constraint on (p:Person) assert (p.name) is unique
- 删除唯一索引
drop constraint on (p:Person) assert (p.name) is unique
1.7 单条最短路径
match (p1:Person{name:"姓名2"}),(p2:Person{name:"姓名10"}), p=shortestpath((p1)-[*..10]-(p2)) return p
shortestpath()用于查询最短路径 [*..10] 表示关系中不超过10度关系
1.8 多条最短路径
match (p1:Person{name:"姓名2"}),(p2:Person{name:"姓名10"}), p=allshortestpaths((p1)-[*..10]-(p2)) return p
1.9 collect 将多个值转换成列表
match (n:ERP_anek) with collect(n) as list call apoc.refactor.mergeNodes(list, {properties:{ziduan:'combine'}}) yield node return count(node)
表ERP_anek是实体,属性为该表字段,数据导入后,将多个实体合并
1.10 unwind 将列表拆分成多个值
WITH [[1, 2],[3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y
依次遍历拆开多个列表
1.11 yield 依次迭代生成对象
CALL db.labels() YIELD label
WHERE label CONTAINS 'User'
RETURN count(label) AS numLabels
1、yield和call 关键字 通常一起使用
2、call 后跟图库已实现的procedure,如各种apoc功能, 而yield则为得到
3、call后需加上 procedure的入参;而yield后可加 procedure的返回值
1.12 merge 有关系则返回,没有则创建关系
match (n:Person{name:"王五"}), (m:Person{name:"赵六"}) merge (n)-[l:LOVE]->(m) return l
match (n),(m) where n=m merge (n)-[t:TABLE{table_name:n.table}]-(m) return t
1.13 optional match 可选择匹配,若匹配结果包含空,则用NULL占位
OPTIONAL MATCH (n)-[r]->(m) RETURN m
匹配结果集中如果有丢的部分,则会用null来补充
1.14 XXX with 字符串开头结尾匹配
- start with 匹配字符串的开头
MATCH (n)
WHERE n.name STARTS WITH '张'
RETURN n
- end with 匹配字符串的结尾
MATCH (n)
WHERE n.name ENDS WITH '三'
RETURN n
1.15 得到边上的节点
- startNode(rel) 得到一条关系rel对应的起始节点
- endNode(rel) 得到一条关系rel对应的中止节点
1.16 得到某节点的id或key
- id(node) 得到某节点的id值
- keys(node) 得到某节点的key
1.16 split 对指定字符串用指定分隔符split
模板 :
split(original, splitDelimiter)
使用splitDelimiter切分original
LOAD CSV WITH HEADERS FROM 'file:///employees.csv' AS row
MERGE (e:Employee {employeeId: row.Id, email: row.Email})
WITH e, row
UNWIND split(row.Skills, ':') AS skill
1.17 count 统计指定标签下节点个数
MERGE (e:Employee {employeeId: row.employeeId, name: row.Name})
RETURN count(e);
统计指定标签下节点个数
1.18 distinct 对返回结果去重
WITH [1,1,2,2] AS coll UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS SET
1.19 linenumber() 返回按行操作后的行号
LOAD CSV FROM '{csv-dir}/artists.csv' AS line RETURN linenumber() AS number, line XXXX
按行导入csv,并返回linenumber
1.20 USING PERIODIC COMMIT 多行语句提交
通常用于批量执行语句中,可将多条语句累计一定量后提交, 如load csv 按行载入数据,可以每1000行提交一版
USING PERIODIC COMMIT 1000
LOAD CSV FROM '{csv-dir}/artists.csv' AS line
1、指示Neo4j在多行之后执行提交
2、减少了事务状态的内存开销
3、提交将每1000行发生一次
1.21 grant 赋权
grant 操作需要企业版,社区版由于无法赋权,所以很多高性能操作无法实现
Grant 赋权 共包含8大类:
1)为图的不同部分定义了写特权:
CREATE -允许创建节点和关系。
DELETE -允许删除节点和关系。
SET LABEL-允许使用SET子句设置指定的节点标签。
REMOVE LABEL-允许使用REMOVE子句删除指定的节点标签。
SET PROPERTY -允许在节点和关系上设置属性。
2)还有一些组合特权,这些特权组合了上述特定特权:
MERGE-允许match,create和set属性以允许MERGE命令。
WRITE -允许在整个图形上进行所有写操作。
ALL GRAPH PRIVILEGES -允许在整个图形上进行所有读取和写入操作。
grant create on graph neo4j elements * to neo4j *给neo4j用户增加对neo4j图库的create权限*
Neo4j Cypher Refcard 4.1 语法使用查找表
1.22 apoc.periodid.iterate 并行可迭代过程 需grant赋权
CALL apoc.periodic.iterate( statement1, statement2, { batchSize:1000, iterateList:true, parallel:false, params:{}, concurrency:50, retries:0 } )
YIELD batches, total
1、建议始终设置iterateList:true,因为这样使得一个批次中所有内查询(由batchSize决定)会作为一个事务被提交、从而提高运行效率。
2、仅当数据库是存储在SSD(固态硬盘)时才使用parallel:true选项,因为SSD具有更好的随机读写速率。如果是物理硬盘则不要使用并行选项,因为这反而会降低整体执行效率。
3、并发数concurrency通常设置成分配给数据库服务运行的CPU内核数的整数倍。例如,如果Neo4j服务器运行在8个CPU内核的虚拟或物理主机上,那么concurrency可以是8、16、24等值。
4、并发执行时,如果不同线程需要对同一数据库对象(节点或关系)进行更新,先执行的线程会对待更新的数据库对象加锁(locking),这时其它线程的更新会被阻塞、并报告“锁获取失败”或者Java NullPointerException空指针错误。
一种解决方法是设置重试次数retries,每次重试会等待100ms。
如果还是出现死锁,则不使用并行执行。
1.23 apoc.cypher.parallel并行化操作
call apoc.cypher.parallel('match (n:ERP_anek),(m) where not m:ERP_anek and n.ziduan = m.ziduan merge (n)-[b:bian{lianlu:n.ziduan}]-(m) return b.lianlu', {table: ['ERP_anek','ERP_crhd','ERP_iseg']},'table') yield value
需要grant 添加权限,而grant 操作需要企业版
未完待续...