【Neo4j cypher命令】 使用

零、引言

图库Neo4j使用cypher语句为基本操作语言,本文总结一些关键字的使用方法

一、关键词总结

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
  1. 行终止标识和系统有关,例如在 Unix 中是 \n,在 Windows 上是 \r\n。 如windows环境导入LOAD CSV FROM 'file:///F:\\code\\java\\helloworld\\artists.csv' AS line
  2. 分隔符必须是逗号,除非用通过 FIELDTERMINATOR 特殊指定
  3. 如果字符串是用双引号引起来的,数据读入后会将双引号去掉
  4. 任何需要转义的字符都可以通过反斜线 \ 来转义
  5. 要访问本地(在数据库服务器上)文件,使用 file:/// 路径。除此之外,可以使用任何 HTTPS,HTTP 和 FTP 协议
  6. LOAD CSV导入数据, 可配合使用apoc.node.create() 动态添加单标签,多标签
  7. LOAD CSV是在线导入(导入数据量和效率一般), 使用neo4j-admin import 是离线导入,必须断服务
CALL apoc.export.cypher.all('export.cypher',{format:'cypher-shell'})
  1. 全量导入图库所有内容,全图导出到 import目录下
  2. 若要载入,需在命令行中执行cat export.cypher | cypher-shell -u neo4j -p neo4j 并重启neo4j服务

1.2 create 创建实体或关系

  1. 最简单的创建实体和关系(不带属性)
    create (n:Person)-[:LOVES]->(m:Dog)
  2. 创建2个或多个属性的实体
    create (z:ziduan{name:"f_name",table:"dianlibiao"}) return count(*)
  3. 创建带属性的实体和关系
    create (n:Person{name:"李四"})-[:FEAR{level:1}]->(t:Tiger{type:"东北虎"})
  4. 对实体间创建关系
    match (n:Person{name:""王五""}), (m:Person{name:"赵六"}) create (n)-[k:KNOW]->(m) return k

1.3 delete 删除实体或关系

  1. 先用match查找已有实体、关系, 再用delete删除关系
    match (n:Person{name:"李四"})-[f:FEAR]->(t:Tiger) delete f
  2. 删除所有节点中的bian关系
    match(m)-[b:bian]-(n) delete b
  3. match查询实体,delete删除实体
    match (n:Person{name:"李四"}) delete n
  4. 同时删除实体和关系
    match(n) detach delete n
  5. 删除所有节点
    match (n) delete n
  6. 删除所有节点并级联删除关系
    match (n) detach delete n
  7. 删除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 表示关系名称
() 圆括号里面表示实体 [] 方括号里面表示关系,都是英文状态下
()-[]->() 表示实体-关系-实体 该关系是有方向的,若要表示无方向的关系,则用: ()-[]-()

  1. 查询所有实体节点
    match(n) return n
  2. 根据id查找实体
match (t:Tiger) where id(t)=1837 return t
match (t:Tiger) where id(t)=1837 delete t
  1. 多度关系查询
match (n:Persion)-[:HAS_PHONE]->(p:Phone)-[:CALL]->(p1: Persion) where n.name=“姓名6” return n, p,p1  limit 10
  1. 利用关系查询, 不限定实体只限定关系的查询
match p=()-[c: CALL]->() return p limit 10
  1. 根据实体属性匹配正则查询, 使用通配符,通配符前要加~
match (n:USERS) where n.name=~'Jack.*' return n limit 10
  1. 包含查询 使用关键词contains
match (n:USERS) where n.name= contains 'J'  return n limit 10
  1. 附带属性多实体查询, 逗号隔开,注意语法
match (n:Person{name:"王五"}), (m:Person{name:"赵六"}) return n,m
  1. 查询多种label节点,并进行过滤
match(n) where n:标签1 or n:标签B  return distinct n;
  • distinct * 关键字表示返回节点不重复
  1. 返回非某几类标签,注意使用 not and 关键字
match(n) where not n:标签1 and not n:标签B  return distinct n;

1.5 set 修改实体标签或属性

  1. 给实体增加标签
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
  1. 给关系增加属性
match (n:Person)-[l:LOVE]->(:Person) set l.date="1990" return n, l                                                           |        |	
  1. 给所有节点增加标签
match(n) set n:table return n

1.6 索引的创建与删除(索引是在属性上创建的,用于加速检索)

  1. 创建索引 (在Person标签的name属性上创建索引)
create index on :Person(name)
  1. 删除索引
drop index on :Person(name)
  1. 创建唯一索引(在实体Person的name属性上创建唯一索引)
create constraint on (p:Person) assert (p.name)  is  unique
  1. 删除唯一索引
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 字符串开头结尾匹配

  1. start with 匹配字符串的开头
  MATCH (n)
  WHERE n.name STARTS WITH '张'
  RETURN n
  1. end with 匹配字符串的结尾
  MATCH (n)
  WHERE n.name ENDS WITH '三'
  RETURN n

1.15 得到边上的节点

  1. startNode(rel) 得到一条关系rel对应的起始节点
  2. endNode(rel) 得到一条关系rel对应的中止节点

1.16 得到某节点的id或key

  1. id(node) 得到某节点的id值
  2. 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 操作需要企业版

未完待续...

posted @ 2021-04-16 12:17  Joshua王子  阅读(1951)  评论(0编辑  收藏  举报