关系型数据 CSV 导入图数据 Neo4j

github链接:

目标

本文演示了将CSV数据导入Neo4j的不同方法以及该过程中可能出现的潜在问题的解决方案。

先决条件

在导入数据之前,您应该熟悉什么是图形数据库,如何构建属性图数据模型以及Cypher查询语言的一些基础知识。所有这些技能都是数据导入过程的一部分。中间

CSV是一个用逗号分隔的值的文件,通常在Excel或其他电子表格工具中查看。可以使用其他类型的值作为定界符,但最标准的是逗号。如今,许多系统和流程已经将其数据转换为CSV格式,以便将文件输出到其他系统,人性化的报告以及其他需求。这是人类和系统已经熟悉的使用和处理的标准文件格式。

为Neo4j提供读取和加载CSV文件的功能有助于减少将数据从各种格式和系统导入Neo4j的麻烦。

导入CSV文件的方法

有几种方法可以将CSV数据导入Neo4j,每种方法都有不同的标准和功能。您选择的选项将取决于数据集的大小,以及您对各种工具的舒适程度。

让我们看看Neo4j可以读取和导入CSV文件的一些方式。

  1. LOAD CSV Cypher命令:此命令是一个很好的起点,可以处理中小型数据集(最多1000万条记录)。
  2. neo4j-admin 批量导入工具:命令行工具,用于直接加载大型数据集。
  3. 水壶导入工具:映射并执行数据处理流程的步骤,并且对于非常大的数据集非常适用,尤其是在开发人员已经熟悉使用此工具的情况下。

我们将简要介绍这些工具中的每一个,它们的操作方式以及如何开始使用一般用例。每个文档的更多文档和信息也将包括在内,以在更复杂的情况下提供帮助。数据质量也可能是任何类型的数据导入任何系统的问题,因此我们将介绍其中一些潜在的困难以及如何解决它们。

使用Cypher的LOAD CSV命令

LOAD CSV子句是Cypher查询语言的一部分。我们的Cypher手册包含一个专门介绍其用法的页面,Neo4j的各种博客,视频,解决方案和其他材料都使用此命令。它使用简单并且广泛适用。 LOAD CSV不只是您的基本数据提取机制,还因为它将多个方面组合到一个操作中。

  • 支持从URI加载/提取CSV数据
  • 直接将输入数据映射到复杂的图/域结构
  • 处理数据转换
  • 支持复杂的计算
  • 创建或合并实体,关系和结构
  为了更好地控制,您可以LOAD CSV使用cypher-shell而不是在浏览器中运行命令。有关更多信息,请参见Cypher shell的手册页。

读取CSV文件

LOAD CSV可以处理本地和远程文件,并且每个文件都有一些语法。这很容易错过,最终会导致访问错误,因此我们将在此处尝试阐明规则。

本地文件file:///在文件名之前带有前缀。Neo4j安全性有一个默认设置,即只能从Neo4j导入目录中读取本地文件,这取决于您的操作系统。Neo4j操作手册中列出了每个操作系统的文件位置。我们建议将文件放在Neo4j的import目录中,因为这样可以保护环境安全。但是,如果您需要访问其他位置的文件,则可以在我们的手册中找到要更改的设置。

例子
//Example 1 - file directly placed in import directory (import/data.csv)
LOAD CSV FROM "file:///data.csv"

//Example 2 - file placed in subdirectory within import directory (import/northwind/customers.csv)
LOAD CSV FROM "file:///northwind/customers.csv"

网络托管文件可以直接使用其URL进行引用,例如https://host/path/data.csv。但是,必须设置权限,以便外部源可以读取文件。有关与在线文件导入相关的访问的更多信息,请参见此知识库文章。

例子
//Example 1 - website
LOAD CSV FROM 'https://neo4j.com/docs/cypher-manual/3.5/csv/artists.csv'

//Example 2 - Google
LOAD CSV WITH HEADERS FROM 'https://docs.google.com/spreadsheets/d/'

LOAD CSV的重要提示

需要牢记一些事情,LOAD CSV以及一些有用的技巧来处理您可能会遇到的各种数据方案。

  • 由于持续不断的优化,较新版本的Neo4j可能会更快。
  • 所有的CSV文件中的数据读取为字符串,所以你需要使用toInteger()toFloat()split()或类似功能的转换数值。
  • 检查您的Cypher导入语句是否有错字。标签,属性名称,关系类型和变量区分大小写
  • 数据越干净,负载越容易。尝试在加载之前处理复杂的清理/操作。

使用LOAD CSV转换数据值

Cypher具有一些清理和转换功能,可帮助清除数据。这些对于处理丢失的数据或将字段拆分为图形的多个值非常有用。

首先,请记住Neo4j不存储空值。可以跳过CSV文件中的空字段或将其替换为中的默认值LOAD CSV

//skip null values
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
WITH row WHERE row.Company IS NOT NULL
MERGE (c:Company {companyId: row.Id})

//set default for null values
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MERGE (c:Company {companyId: row.Id, hqLocation: coalesce(row.Location, "Unknown")})

//change empty strings to null values (not stored)
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MERGE (c:Company {companyId: row.Id})
SET c.emailAddress = CASE trim(row.Email) WHEN "" THEN null ELSE row.Email END 

接下来,如果您在CSV中有一个要拆分的项目列表的字段,则可以使用Cypher split()函数来分隔单元格中的数组。

//split string of employee skills into separate nodes
LOAD CSV FROM 'file:///data.csv' AS row
MERGE (e:Employee {employeeId: row.Id})
UNWIND split(row.skills, ',') AS skill
MERGE (s:Skill {name: skill})
MERGE (e)-[r:HAS_EXPERIENCE]->(s);

可以使用条件转换CASE。当我们检查空值或空字符串时,您看到了一个示例,但让我们看另一个示例。

//set businessType property based on shortened value in CSV
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
WITH row,
(CASE row.BusinessType
 WHEN 'P' THEN 'Public'
 WHEN 'R' THEN 'Private'
 WHEN 'G' THEN 'Government'
 ELSE 'Other' END) AS type
MERGE (c:Company {companyId: row.CompanyId})
SET c.businessType = type
RETURN *

优化LOAD CSV以提高性能

通常,有多种方法可以提高数据加载期间的性能,这在处理大量数据或复杂加载时特别有用。

为了改善在图形中插入或更新唯一实体(使用更新MERGEMATCH使用更新),可以为计划合并或匹配的每个标签和属性创建声明的索引和约束。

  为了获得最佳性能,总是MATCHMERGE与编索引的主键属性的单个标签上。

您还应该将节点和关系创建分为单独的语句。例如,代替以下内容:

MERGE (e:Employee {employeeId: row.employeeId})
MERGE (c:Company {companyId: row.companyId})
MERGE (e)-[r:WORKS_FOR]->(c)

您可以这样写:

LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MERGE (e:Employee {employeeId: row.employeeId})
RETURN count(e);

LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MERGE (c:Company {companyId: row.companyId})
RETURN count(c);

LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MATCH (e:Employee {employeeId: row.employeeId})
MATCH (c:Company {companyId: row.companyId})
MERGE (e)-[r:WORKS_FOR]->(c)
RETURN count(*);

这样,负载一次只执行一次导入,并且可以快速而有效地遍历大量数据,从而减少了繁重的处理。

当要加载的数据量太大而无法容纳到内存中时,可以使用两种不同的方法来防止在数据加载期间内存不足。

  1. 使用将批处理导入到各节中PERIODIC COMMIT。可以在该LOAD CSV子句之前添加此子句,以告诉Cypher在清除内存和事务状态之前仅处理文件的这么多行。欲了解更多信息,请参见手册页上PERIODIC COMMIT
USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
MERGE (pet:Pet {petId: row.PetId})
MERGE (owner:Owner {ownerId: row.OwnerId})
 ON CREATE SET owner.name = row.OwnerName
MERGE (pet)-[r:OWNED_BY]->(owner)
  1. 避免使用EAGER运算符。有些语句会插入比所需行更多的行,从而在前面增加了额外的处理。为避免这种情况,您可以PROFILE对查询运行,以查看它们是否使用EAGER加载并修改查询或对同一文件运行多次传递,因此它不会这样做。可在Mark的博客文章中找到有关EAGER加载以及如何避免的更多信息。
  2. 调整堆和内存上数据库的配置,以避免页面错误。为了帮助处理大量事务,您可以增加数据库的一些配置设置,然后重新启动实例以使它们生效。通常,您可以在每2 GB堆的单个事务中创建或更新1M记录。在neo4j.conf
    • dbms.memory.heap.initial_sizedbms.memory.heap.max_size:设置为至少4G。
    • dbms.memory.pagecache.size:理想情况下,其值应足以将整个数据库保留在内存中。

加载CSV资源

  • 如何:在Neo4j Desktop中导入CSV
  • 密码手册:LOAD CSV
  • 示例:导入罗斯文数据集
  • 视频:在现实世界中加载CSV

大数据集批量导入器

LOAD CSV非常适合导入中小型数据(最多1000万条记录)。对于大于此的数据集,我们可以访问命令行批量导入器。该neo4j-admin import工具允许您通过指定节点文件和关系文件将CSV数据导入到空数据库中。

我们要使用它将订单数据导入Neo4j:客户,订单和订购的产品

该工具位于中/bin/neo4j-admin,并按以下方式使用:

bin/neo4j-admin import --id-type=STRING \
                       --nodes:Customer=customers.csv --nodes=products.csv  \
                       --nodes="orders_header.csv,orders1.csv,orders2.csv" \
                       --relationships:CONTAINS=order_details.csv \
                       --relationships:ORDERED="customer_orders_header.csv,orders1.csv,orders2.csv"

用于此导入的前几行数据如下所示:

表1. customer.csv
customerId:ID(客户) 名称

23

熟食公司

42

美味面包店

表2. products.csv
productId:ID(产品) 名称 价钱 :标签

11

巧克力

10

产品;食品

表3.orders_header.csv,orders1.csv,orders2.csv
orderId:ID(订单) 日期 customerId:IGNORE

1041

2015-05-10

130

23

1042

2015-05-12

20

42

表4. order_details.csv
:START_ID(订购) 价钱 :END_ID(产品)

1041

13

130

11

1042

2

20

11

表5. customer_orders_header.csv,orders1.csv,orders2.csv
:END_ID(订购) 日期:IGNORE 总计:IGNORE :START_ID(客户)

1041

2015-05-10

130

23

1042

2015-05-12

20

42

  如果调用bin/neo4j-admin import不带参数的话,它将列出一个全面的帮助页面。

重复的--nodes--relationships参数是同一实体(即具有相同列结构)的多个(可能是拆分的)CSV文件的组。

每组中的所有文件都被视为可以串联为一个大文件。甲标题行中的组的所述第一文件或在一个单独的,单行文件是必需的。将标头放在单独的文件中,比将其包含在数GB的文本文件中更容易处理和编辑。还支持压缩文件。

  • --id-type=STRING指示所有:ID列包含字母数字值(有用于纯数字ID的优化)。
  • customers.csv直接将其作为带有:Customer标签的节点导入,并将属性直接从文件中获取。
  • Product节点遵循从:LABEL列中获取节点标签的相同模式。
  • Order一个头和两个内容文件-节点由3个文件拍摄。
  • 键入:CONTAINSorder_details.csv订单项关系是通过创建的,通过ID将订单与包含的产品相关联。
  • 通过再次使用订单CSV文件将订单连接到客户,但是这次使用了不同的标题,即:IGNORE的不相关列。

列名称用于节点和关系的属性名称。在特定的列上有特定的标记,我们将对其进行解释。

  • name:ID –全局ID列,用于在以后重新连接时查找节点。
    • 如果保留该属性名称,则不会存储该属性名称(临时名称),这是该名称--id-type所指的。
    • 如果您在实体之间有重复的ID,则必须在括号中提供实体(id-group),例如:ID(Order)
    • 如果您的ID在全球范围内是唯一的,则可以将其保留。
  • :LABEL–节点的标签列。多个标签可以用定界符分隔。
  • :START_ID:END_ID–涉及节点ID的关系文件列。对于id组,请使用:END_ID(Order)
  • :TYPE –指定关系类型的列。
  • 所有其他列均视为属性,但如果为空或用注释,则会跳过:IGNORE
  • 类型转换可以通过与像指标后面添加名称:INT:BOOLEAN等等。

有关此标头格式和工具的更多详细信息,请参见Neo4j手册中的文档以及随附的教程。

CSV数据质量

现实世界的数据是混乱的。每次使用数据时,您都会看到一些需要清除或转换的值,然后才能将其移至另一个系统。较小的语法错误,格式说明,一致性或正确的引用,甚至对数据要求或标准的不同假设,都很容易造成大量的清理工作。

我们将重点介绍将数据从其他系统加载到Neo4j时容易遗漏的一些数据质量问题,并尝试帮助避免数据导入和清理问题。

常见陷阱

标头与数据不一致(缺少,列太多,标 头中的分隔符不同)验证标头与文件中的数据匹配。在此阶段调整格式,定界符,列等将在以后节省大量时间。

整个文件中多余或缺少的引号如果 未加引号的文本中间有独立的双引号或单引号,或者带引号的文本中未转义的引号会导致读取文件以加载的问题。最好是转义或删除流浪引号。Cypher样式指南和知识库文章中提供了正确转义的文档。

文件中的 特殊字符或换行符处理文件中的任何特殊字符时,请确保将其引号或将其删除。对于带引号或不带引号的字段中的换行符,请为其添加引号或将其删除。

换行符不一致 计算机处理不好的一件事是数据不一致。确保换行符始终一致。我们建议选择Unix风格以与Linux系统兼容(导入工具的通用格式)。

二进制零,文件开头的BOM字节顺序标记(2个UTF-8字节)或其他非文本字符 任何不寻常的字符或特定于工具的格式(Excel或Word)有时都隐藏在应用程序工具中,但在基本编辑器。如果您在文件中遇到这些类型的字符,最好将其完全删除。

工具类

如上所述,某些应用程序具有特殊的格式以使文档看起来不错,但是这种隐藏的额外代码无法由常规文件阅读器和脚本处理。其他时候,很难找到小的语法更改或对包含大量数据的文件进行广泛的调整。

为了处理这些类型的情况或常规数据清除,有许多工具可帮助您检查和验证CSV数据文件。

基本工具(例如hexdump,vi,emacs,UltraEdit和Notepad ++)可以很好地处理基于快捷方式的命令,以编辑和处理文件。但是,还有其他更有效或用户友好的选项可用于数据清除和格式化。

  • CSVKit –一组Python工具,可提供CSV文件的统计信息(csvstat),搜索(csvgrep)等。
  • CSVLint –用于验证CSV文件的在线服务。您可以上传文件或提供URL进行加载。
  • Papa Parse –一个用于CSV解析的综合Javascript库,使您可以流式传输CSV数据,并提供有关问题的良好,易于阅读的错误报告。
  • Cypher – Cypher看到的将是导入的内容,因此您可以利用它来发挥自己的优势。使用LOAD CSV而不创建图形结构只会输出样本,计数或分布,从而有可能检测不正确的标题列计数,定界符,引号,转义符或标题名称拼写。
// assert correct line count
LOAD CSV FROM "file-url" AS line
RETURN count(*);

// check first 5 line-sample with header-mapping
LOAD CSV WITH HEADERS FROM "file-url" AS line
RETURN line
LIMIT 5;

 

 

你可能感兴趣的:(知识图谱,图数据库)