neo4j批量导入数据 摘要本文系统介绍了 Neo4j 批量导入数据的完整流程。首先阐述了构建知识图谱基准的三个核心模块节点、关系、属性键和本体设计原则。接着详细说明了 CSV 文件构建要素包括如何按实体集和关系类型划分表格。最后通过具体示例演示了从准备 CSV 文件到编写 Cypher 导入语句包括建立约束、导入节点、建立关系的完整操作步骤为高效、结构化地将数据导入 Neo4j 图数据库提供了实用指南。目录1. 构建基准2. csv文件构建要素3. csv导入neo4j3.1. 实体表node.csv3.1.1 列含义3.1.2 csv文件批量导入实体语句3.2. 关系表edge.csv3.2.1 列含义3.2.2 csv文件批量导入关系语句3.3 知识图谱构建以及neo4j导入示例数据3.3.1 准备两个 CSV 文件3.3.1.1 节点表nodes.csv3.3.1.2 关系表edges.csv3.3.2 编写 Cypher 导入语句3.3.2.1 批量导入节点3.3.2.2 批量导入关系核心步骤1. 构建基准neo4j直观来看包含nodes、relationships和property keys三大模块首先进行本体设计本体可以将其看成是schema是指元数据即表示数据的数据。nodes中的一个节点可以看成是一个本体要将同种特性的实体放在一个集合nodes中以颜色区分以颜色联想类别一个集合是一种颜色将实体之间的关系理清楚要解释称成RDF(主谓宾)的关系如羊吃草也就是后文所提到的关系表2. csv文件构建要素由于不同的实体集具有不同的属性所以在一个实体集可以提取出相同的属性名因此不同的集合放在不同的csv表中。不同的实体集表示一类例如在行业标杆知识图谱northwind中将实体分为category、customer、order、product和supplier五大类那么要将这五大类分别做成五个csv表格不同的关系表示一类例如在northwind中将关系分为orders、part_of、purchased、supplies大类那么要将这六大类分别做成六个csv表格实体之间的关系为order-orders-productproduct-part_of-categorycustomer-purchased-ordersupplier-supplies-product3. csv导入neo4j要将不同的实体和关系放在不同的表中这样可以很好的整理表结构并排查错误。基本的方法如下准备两张表实体表和关系表3.1. 实体表node.csvnode需修改为实际的节点名称包含列编码、名称、描述、实体属性名1、实体属性名2、…3.1.1 列含义节点id对每一条实体进行编码该节点下的一级实体编码为N01二级编码N0101…以此类推名称具体名字描述如果该实体没有相关属性说明那就简单描述这个实体或者提取出的有价值的信息无法放入任何属性中时加入描述内实体属性名1对事物性质及其相互关系的抽象概括这里的属性名需要修改为实际已经概括好的属性3.1.2 csv文件批量导入实体语句属性名需要修改为实际已经概括好的实际属性// 1. 建立唯一性约束确保性能只需执行一次 CREATE CONSTRAINT FOR (p:需修改为实际的节点名称) REQUIRE p.编码 IS UNIQUE; // 2. 导入节点数据这里如果有更多的属性需要在后面加 LOAD CSV WITH HEADERS FROM file:///nodes.csv AS row MERGE (p:需修改为实际的节点名称 {编码: row.编码}) SET p.名称 row.名称, p.描述 row.描述, p.属性名1 row.属性名1, p.属性名2 row.属性名2;3.2. 关系表edge.csvedge需修改为实际的关系名称包含列源节点编码,目标节点编码,关系类型,关系属性名1,关系属性名2,…3.2.1 列含义源节点编码关系起始节点编码在实体中已经创建好的编码目标节点编码关系指向节点编码在实体中已经创建好的编码关系类型edge该表的关系名称关系属性名1对事物性质及其相互关系的抽象概括关系属性名需修改为实际已经概括的属性3.2.2 csv文件批量导入关系语句节点都建好后读取关系表利用MATCH精确定位头尾节点然后把线连上。source和target代表节点中的实体属性名需要修改为实际已经概括好的实际属性当源节点编码与目标节点编码处于同一个节点(如两个实体都处于电价节点中)时edges可改为实际关系LOAD CSV WITH HEADERS FROM file:///edges.csv AS row // 1. 匹配出线两端的节点 MATCH (source:需修改为实际的节点名称 {编码: row.源节点编码}) MATCH (target:需修改为实际的节点名称 {编码: row.目标节点编码}) // 2. 建立带有时效属性的关系保持原样 MERGE (source)-[r:需修改为实际的关系名称]-(target) SET r.关系属性名1 row.关系属性名1, r.关系属性名2 row.关系属性名2;当源节点编码与目标节点编码处于不同的节点(如电价与用户群体)时edges可改为实际关系LOAD CSV WITH HEADERS FROM file:///edges.csv AS row // 1. 匹配出线两端的节点 MATCH (source:实际节点名称1 {编码: row.源节点编码}) MATCH (target:实际节点名称2 {编码: row.目标节点编码}) // 2. 建立带有时效属性的关系保持原样 MERGE (source)-[r:需修改为实际的关系名称]-(target) SET r.关系属性名1 row.关系属性名1, r.关系属性名2 row.关系属性名2;3.3 知识图谱构建以及neo4j导入示例数据3.3.1 准备两个 CSV 文件请在 csv 中准备以下两张表保持数据中的空格和括号原样不动并分别另存为nodes.csv节点表和edges.csv关系表放入 Neo4j 的\import目录下。3.3.1.1 节点表nodes.csv只记录每个独立实体本身的属性不包含任何连线信息将其保存在csv文件中编码,名称,层级 P01,交通工具,大类 P0101,电动汽车,子类 P010101,轿车,孙类 P01010101,Model 3,车型 P0101010101,Model 3 后轮驱动版,SKU P0101010102,Model 3 长续航全轮驱动版,SKU P0101010103,Model 3 高性能全轮驱动版,SKU保存结果如下编码名称层级P01交通工具大类P0101电动汽车子类P010101轿车孙类P01010101Model 3车型P0101010101Model 3 后轮驱动版SKUP0101010102Model 3 长续航全轮驱动版SKUP0101010103Model 3 高性能全轮驱动版SKU3.3.1.2 关系表edges.csv只记录连线。通过头尾节点的编码进行映射并且可以给关系本身赋予属性如关系权重、创建年份等将其保存在csv文件中以,分隔成4列源节点编码,目标节点编码,关系类型,创建年份 P01,P0101,包含子类,2026 P0101,P010101,包含子类,2026 P010101,P01010101,包含子类,2026 P01010101,P0101010101,包含子类,2026 P01010101,P0101010102,包含子类,2026 P01010101,P0101010103,包含子类,2026保存结果如下源节点编码目标节点编码关系类型创建年份P01P0101包含子类2026P0101P010101包含子类2026P010101P01010101包含子类2026P01010101P0101010101包含子类2026P01010101P0101010102包含子类2026P01010101P0101010103包含子类20263.3.2 编写 Cypher 导入语句在 Neo4j 浏览器中按照以下两个步骤执行命令3.3.2.1 批量导入节点首先把所有“圆圈”立在数据库里。为了保证连线时的检索性能我们强烈建议先为编码建立唯一性约束索引。// 1. 建立唯一性约束确保性能只需执行一次 CREATE CONSTRAINT FOR (p:产品) REQUIRE p.编码 IS UNIQUE; // 2. 导入节点数据 LOAD CSV WITH HEADERS FROM file:///nodes.csv AS row MERGE (p:产品 {编码: row.编码}) SET p.名称 row.名称, p.层级 row.层级;3.3.2.2 批量导入关系核心步骤节点都建好后读取关系表利用MATCH精确定位头尾节点然后把线连上。(注意由于 Cypher 不支持动态的[:row.关系类型]语法如果你的关系表里有多种不同的关系名称标准的做法是利用CALL apoc.create.relationship插件或者在导入时通过WHERE分类导入。这里以你最核心的包含子类关系为例进行标准编写)LOAD CSV WITH HEADERS FROM file:///edges.csv AS row // 1. 匹配出线两端的节点 MATCH (source:产品 {编码: row.源节点编码}) MATCH (target:产品 {编码: row.目标节点编码}) // 2. 建立带有时效属性的关系保持原样 MERGE (source)-[r:包含子类]-(target) SET r.创建年份 row.创建年份;