1. 注释
注释: 所有cypher脚本语言使用’//'来注释
2. 查询
2.1 查看当前用户
CALL dbms.showCurrentUser();
2.2 查看所有类型元数据关系
CALL db.schema.visualization()
如下所示,展示了实体集合的所有关系
2.3 查询某一实体的所有关系,数据量大注意用limit限制,防止内存溢出
MATCH p=(n:zly_demo_diff_type)-[r]-() return p
2.4 通过条件查找某一实体
match (n:person) where n.age=24 return n
2.5 查询计划
explain
2.6 对结果集进行去重查询
match (n) return distinct n.name;
2.7 对查询结果进行排序和分页
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)RETURN a,count(*) AS appearancesORDER BY appearances DESC SKIP 3 LIMIT 10;
2.8 合并查询(两个结果集结构相同)
MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN actor.name AS name, type(r) AS acted_in, movie.title AS title
UNION (ALL)
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN director.name AS name, type(r) AS acted_in, movie.title AS title
2.9 with语法(参考hive with as语法,用法类似)
注意with的结果集必须要有命名,对with的结果在做where条件筛选
MATCH (n:Person)-[r:ACTED_IN]->(o:Movie) with o,count(r) as count_r where count_r > 8 RETURN o
2.10 添加索引,并使用索引快速找到节点(数据量大,构建关系、查找实体和关系)
//创建索引
create index on:actor(name)
//使用带有索引的属性快速查找节点
MATCH (n:actor { name: "Tom Hanks" })RETURN n;
2.11 查看索引
:schema
2.12 日常用到查询某一个具体实体的一层级的关系使用如下带条件语句即可
MATCH p=(n:zly_demo_old_person)-[r]-() where n.old_name='顾正泉' return p
如下所示,只展示一层级的关系
3. 创建
3.1 创建可重复的节点或关系
CREATE (a:Person {name:'Brie Larson', born:1989}) RETURN a
3.2 创建或更新节点
如下merge语句有两个子语句:ON CREATE和ON MATCH。使用ON CREATE是为新创建的节点设置值。使用ON MATCH是为更新现有节点的值。
MERGE (a:Person {name:'Brie Larson'})
ON CREATE SET a.born = 1989
ON MATCH SET a.stars = COALESCE(a.stars, 0) + 1
RETURN a
3.3 创建或更新关系
MATCH (a:Person {name:'Brie Larson'}), (b:Movie {title:'Captain Marvel'})
MERGE (a)-[r:ACTED_IN]->(b) SET r.roles = ['Carol Danvers']
RETURN a,r,b
4. 删除
4.1 同时删除关系和节点
MATCH (r:Loc) DETACH DELETE r
4.2 指定具体属性可以具体删除包含该属性的节点并连同他的关系一起删除
MATCH (n:actor) where n.age=24 detach delete n;
4.3 删除索引
drop index on :yljg(pk_yl_yljg)
4.4 删除所有数据
MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r
5. 修改
5.1 使用set语句进行修改
5.2 使用merge语句进行更新
6. 批量数据操作
当对数据量级别特别大的图谱数据进行操作时,如配置节点关系、删除节点关系,使用普通语法除了等待时间长以外,几乎都会内存溢出报错,此时可以使用批量操作语法
如下操作为批量删除old_person节点,periodic结合apoc语法
CALL apoc.periodic.commit("
MATCH (n:old_person) WITH n LIMIT $limit detach DELETE n RETURN count(*)",{limit: 10000})
YIELD updates, executions, runtime, batches
RETURN updates, executions, runtime, batches;
或在导入csv时,直接使用periodic语法
:auto USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:///浙里养三期知识图谱演示/床位实体.csv" AS row
CREATE (:zly_demo_bed {bed_floor: row.`床位实体`});
注意事项:
apoc将大量应用于,jdbc数据导入,以及批量数据处理,目前使用情况正常,但在关系匹配时,需要将并行度设置为false,否则只能创建一部分关系并且剩下的创建失败也不会报错【暂时没有找到原因】
关系匹配,parallel设为false
CALL apoc.periodic.iterate(
'CALL apoc.load.jdbc("jdbc:mysql://localhost/irs?user=root&password=123456&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC","select pk_yl_yljg_admission,fk_yl_yljg from in_old")',
'match(m:old_person{pk_yl_yljg_admission:row.pk_yl_yljg_admission}),(n:yljg{pk_yl_yljg:row.fk_yl_yljg}) create (m)-[r:入住机构]->(n)',
{ batchSize:2000,parallel:false, iterateList:true,retries:20}
)
7. 自动化脚本
7.1 编辑import.cypher文件,后缀为cypher,命名自定义
注意cypher脚本文件内,每段语句结束使用’;'符,注释使用‘//’符
//cypher执行脚本
// 导入各类实体
LOAD CSV WITH HEADERS FROM "file:///demo/床位实体.csv" AS row
CREATE (:zly_demo_bed {bed_floor: row.`床位实体`});
LOAD CSV WITH HEADERS FROM "file:///demo/村社实体.csv" AS row
CREATE (:zly_demo_village {village_name: row.`村社实体`});
LOAD CSV WITH HEADERS FROM "file:///demo/机构实体.csv" AS row
CREATE (:zly_demo_institution {insti_name: row.`机构实体`});
LOAD CSV WITH HEADERS FROM "file:///demo/家庭类型实体.csv" AS row
CREATE (:zly_demo_diff_type {diff_type: row.`家庭类型实体`});
LOAD CSV WITH HEADERS FROM "file:///demo/老人实体.csv" AS row
CREATE (:zly_demo_old_person {old_name: row.`姓名`});
LOAD CSV WITH HEADERS FROM "file:///demo/身体能力实体.csv" AS row
CREATE (:zly_demo_assess_level{assess_result: row.`身体能力情况`});
LOAD CSV WITH HEADERS FROM "file:///demo/性别实体.csv" AS row
CREATE (:zly_demo_sex{sex_value: row.`性别实体`});
//对各类实体添加索引
CREATE INDEX ON :zly_demo_bed(bed_floor);
CREATE INDEX ON :zly_demo_village(village_name);
CREATE INDEX ON :zly_demo_institution(insti_name);
CREATE INDEX ON :zly_demo_diff_type(diff_type);
CREATE INDEX ON :zly_demo_old_person(old_name);
CREATE INDEX ON :zly_demo_assess_level(assess_result);
CREATE INDEX ON :zly_demo_sex(sex_value);
//导入各类实体动态关系
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_old_person {old_name: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_institution {insti_name: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_sex {sex_value: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_village {village_name: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_bed {bed_floor: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_diff_type {diff_type: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
LOAD CSV WITH HEADERS FROM "file:///demo/实体关系.csv" AS row
MATCH (m:zly_demo_old_person {old_name: row.`姓名`})
MATCH (n:zly_demo_assess_level {assess_result: row.`实体`})
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;
7.2 进入安装目录bin目录下,执行import.cypher文件
cat ./import.cypher | ./cypher-shell -u 用户名 -p 密码
7.3 若编辑自动化脚本,可使用shell脚本语言,并设置调度时间
7.4 注意
若脚本内存在直接create的实体直接的静态关系,不能使用中文,否则将出现如下情况
目前,使用脚本读取动态化关系可以正常创建该类关系
8. 动态关系与静态关系定义区分
当我们直接创建节点,并配置节点直接的关系时,这种关系则是写死的静态关系,如下语句则是创建了一个静态关系,‘父亲’改关系属性为静态。
MATCH (m:person{name:"jzy"})
,(n:person{name:"lyf"})
CREATE (m)<-[r:`父亲`]-(n)
RETURN m,r,n
但很多时候是存在各种各类的关系,提供的关系属性多为‘实体–关系—实体’的三元组,不可能一一手动去create配置,此时需要使用apoc组件,进行动态配置
动态配置语法:
m,n为对应需要配置关系的节点
CALL apoc.merge.relationship(m,row.`关系`,{},{},n) yield rel return *;