教程:将关系数据库中的数据导入 Neo4j

简介

本教程演示了将数据从关系数据库(PostgreSQL)导出并导入到图数据库(Neo4j)的过程。您将学习如何通过转换模式和使用导入工具,将数据从关系系统迁移到图系统中。

或者,您可以

本指南使用了一个特定的数据集,但其原理可以应用于任何数据领域并重复使用。

您应该对属性图模型有基本的了解,并知道如何将数据建模为图。

关于数据领域

在本指南中,我们将使用 Northwind 数据集,这是一个常用的 SQL 数据集。该数据描绘了一个产品销售系统,用于存储和跟踪客户、产品、客户订单、仓库库存、运输、供应商,甚至是员工及其销售区域。尽管 NorthWind 数据集常用于演示 SQL 和关系数据库,但这些数据同样可以构建为图。

Northwind 数据集的实体关系图 (ERD) 如下所示。

Northwind diagram

首先,这是一个相当庞大且详细的模型。我们可以为我们的示例将其简化,并选择对我们的图至关重要的实体——换句话说,那些最能从观察连接中获益的实体。对于我们的用例,我们真正想要优化的是与订单相关的关系——涉及哪些产品(以及这些产品的类别和供应商)、哪些员工负责这些订单,以及这些员工的经理。

利用这些业务需求,我们可以将模型缩减为这些核心实体。

Northwind diagram focus

开发图模型

要将数据从关系数据库导入到图中,您需要做的第一件事是将关系数据模型转换为图数据模型。决定如何将表和行结构化为节点和关系,取决于什么对您的业务需求最重要。

有关将图模型适应不同场景的更多信息,请查看我们的建模设计指南。

在从关系模型导出图模型时,您应记住以下几条通用准则。

  1. 行 即 节点。

  2. 表名 即 标签名。

  3. 连接或外键 即 关系。

牢记这些原则,我们可以按照以下步骤将我们的关系模型映射到图

行转节点,表名转标签

  1. Orders 表中的每一行都成为图中的一个节点,并使用 Order 作为标签。

  2. Products 表中的每一行都成为一个节点,并使用 Product 作为标签。

  3. Suppliers 表中的每一行都成为一个节点,并使用 Supplier 作为标签。

  4. Categories 表中的每一行都成为一个节点,并使用 Category 作为标签。

  5. Employees 表中的每一行都成为一个节点,并使用 Employee 作为标签。

连接转关系

  1. Suppliers 和 Products 之间的连接成为名为 SUPPLIES 的关系(供应商供应产品)。

  2. Products 和 Categories 之间的连接成为名为 PART_OF 的关系(产品属于某个类别)。

  3. Employees 和 Orders 之间的连接成为名为 SOLD 的关系(员工销售了订单)。

  4. Employees 表与自身(一元关系)的连接成为名为 REPORTS_TO 的关系(员工拥有上级经理)。

  5. Orders 和 Products 之间通过连接表(Order Details)的连接,成为名为 CONTAINS 的关系,并带有 unitPrice、quantity 和 discount 等属性(订单包含产品)。

如果我们把这个转换画在白板上,我们就得到了这个图数据模型。

northwind graph simple arr

当然,我们也可以决定引入关系模型中的其余实体,但目前,我们将保持这个较小的图模型。

图模型与关系模型有何不同?

  • 没有空值 (nulls)。不存在的值条目(属性)只是不出现而已。

  • 它更详细地描述了关系。例如,我们知道员工“销售”(SOLD) 了订单,而不是在 Orders 和 Employees 表之间有一个外键关系。如果我们愿意,还可以选择为该关系添加更多元数据。

  • 任何一种模型都可以进行更高级的规范化。例如,地址在几个表中被反规范化了,但本来可以放在一个单独的表中。在未来版本的图模型中,我们可能还会选择将地址从 Order(或 Supplier 或 Employee)实体中分离出来,并创建单独的 Address 节点。

将关系表导出为 CSV

幸运的是,这一步已经为您完成,您将在本指南后面使用 Northwind 数据。

但是,如果您正在处理其他数据领域,则需要将数据从关系表中取出,并将其转换为其他格式以便加载到图中。许多系统都能处理的一种常见格式是逗号分隔值 (CSV) 的扁平文件。

以下是我们为您运行的将 Northwind 数据导出为 CSV 文件的示例脚本。

export_csv.sql

COPY (SELECT * FROM customers) TO '/tmp/customers.csv' WITH CSV header;
COPY (SELECT * FROM suppliers) TO '/tmp/suppliers.csv' WITH CSV header;
COPY (SELECT * FROM products)  TO '/tmp/products.csv' WITH CSV header;
COPY (SELECT * FROM employees) TO '/tmp/employees.csv' WITH CSV header;
COPY (SELECT * FROM categories) TO '/tmp/categories.csv' WITH CSV header;

COPY (SELECT * FROM orders
      LEFT OUTER JOIN order_details ON order_details.OrderID = orders.OrderID) TO '/tmp/orders.csv' WITH CSV header;

如果您想使用自己的 Northwind RDBMS 自行创建 CSV 文件,可以运行此脚本,命令为 psql -d northwind < export_csv.sql。

注意:除非您想针对自己的 Northwind RDBMS 执行此脚本,否则无需运行它。

使用 Cypher 导入数据

您可以使用 Cypher® 的 LOAD CSV 命令将 CSV 文件的内容转换为图结构。

当您使用 LOAD CSV 在数据库中创建节点和关系时,对于 CSV 文件的存放位置有两个选择:

  • 位于您可以管理的 Neo4j 实例的 import 文件夹中。

  • 从公开可用的位置(例如 S3 存储桶或 GitHub 地址)加载。如果您使用 Neo4j AuraDB 或 Neo4j Sandbox,则必须使用此选项。

如果您想为您管理的 Neo4j 实例使用 CSV 文件,可以将 CSV 文件从 GitHub 上的 Northwind 文件 复制并放置到您的 Neo4j DBMS 的 import 文件夹中。

您可以使用 Cypher 的 LOAD CSV 语句读取每个文件,并在其后添加 Cypher 子句,以获取行/列数据并将其转换为图。

接下来,您将运行 Cypher 代码以:

  1. 从 CSV 文件中加载节点。

  2. 为图中的数据创建索引和约束。

  3. 创建节点之间的关系。

创建 Order 节点

执行此 Cypher 块以在数据库中创建 Order 节点

// Create orders
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MERGE (order:Order {orderID: row.OrderID})
  ON CREATE SET order.shipName = row.ShipName;

如果您已将 CSV 文件放入 import 文件夹中,则应使用此代码语法从本地目录加载 CSV 文件

// Create orders
LOAD CSV WITH HEADERS FROM 'file:///orders.csv' AS row
MERGE (order:Order {orderID: row.OrderID})
  ON CREATE SET order.shipName = row.ShipName;

此代码在数据库中创建了 830 个 Order 节点。

您可以通过执行以下代码来查看数据库中的某些节点

MATCH (o:Order) return o LIMIT 5;

图视图是

import guide Orders

表视图包含这些节点属性值

o

{"shipName":Vins et alcools Chevalier,"orderID":10248}

{"shipName":Toms Spezialitäten,"orderID":10249}

{"shipName":Hanari Carnes,"orderID":10250}

{"shipName":Victuailles en stock,"orderID":10251}

{"shipName":Suprêmes délices,"orderID":10252}

您可能注意到并未导入 CSV 文件中的所有字段列。通过您的语句,您可以选择节点需要哪些属性,哪些可以忽略,哪些可能需要导入到其他节点类型或关系中。您可能还会注意到使用了 MERGE 关键字,而不是 CREATE。虽然我们相当确定 CSV 文件中没有重复项,但使用 MERGE 是确保数据库中实体唯一的良好实践。

创建 Product 节点

执行此代码以在数据库中创建 Product 节点

// Create products
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv' AS row
MERGE (product:Product {productID: row.ProductID})
  ON CREATE SET product.productName = row.ProductName, product.unitPrice = toFloat(row.UnitPrice);

此代码在数据库中创建了 77 个 Product 节点。

您可以通过执行此代码查看数据库中的一些节点

MATCH (p:Product) return p LIMIT 5;

图视图是

import guide Products

表视图包含这些节点属性值

p

{"unitPrice":18.0,"productID":1,"productName":Chai}

{"unitPrice":19.0,"productID":2,"productName":Chang}

{"unitPrice":10.0,"productID":3,"productName":Aniseed Syrup}

{"unitPrice":22.0,"productID":4,"productName":Chef Anton’s Cajun Seasoning}

{"unitPrice":21.35,"productID":5,"productName":Chef Anton’s Gumbo Mix}

创建 Supplier 节点

执行此代码以在数据库中创建 Supplier 节点

// Create suppliers
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/suppliers.csv' AS row
MERGE (supplier:Supplier {supplierID: row.SupplierID})
  ON CREATE SET supplier.companyName = row.CompanyName;

此代码在数据库中创建了 29 个 Supplier 节点。

您可以通过执行此代码查看数据库中的一些节点

MATCH (s:Supplier) return s LIMIT 5;

图视图是

import guide Suppliers

表视图包含这些节点属性值

s

{"supplierID":1,"companyName":Exotic Liquids}

{"supplierID":2,"companyName":New Orleans Cajun Delights}

{"supplierID":3,"companyName":Grandma Kelly’s Homestead}

{"supplierID":4,"companyName":Tokyo Traders}

{"supplierID":5,"companyName":Cooperativa de Quesos 'Las Cabras'}

创建 Employee 节点

执行此代码以在数据库中创建 Supplier 节点

// Create employees
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/employees.csv' AS row
MERGE (e:Employee {employeeID:row.EmployeeID})
  ON CREATE SET e.firstName = row.FirstName, e.lastName = row.LastName, e.title = row.Title;

此代码在数据库中创建了 9 个 Employee 节点。

您可以通过执行此代码查看数据库中的一些节点

MATCH (e:Employee) return e LIMIT 5;

图视图是

import guide Employees

表视图包含这些节点属性值

e

{"lastName":Davolio,"firstName":Nancy,"employeeID":1,"title":Sales Representative}

{"lastName":Fuller,"firstName":Andrew,"employeeID":2,"title":Vice President, Sales}

{"lastName":Leverling,"firstName":Janet,"employeeID":3,"title":Sales Representative}

{"lastName":Peacock,"firstName":Margaret,"employeeID":4,"title":Sales Representative}

{"lastName":Buchanan,"firstName":Steven,"employeeID":5,"title":Sales Manager}

创建 Category 节点

// Create categories
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/categories.csv' AS row
MERGE (c:Category {categoryID: row.CategoryID})
  ON CREATE SET c.categoryName = row.CategoryName, c.description = row.Description;

此代码在数据库中创建了 8 个 Category 节点。

您可以通过执行此代码查看数据库中的一些节点

MATCH (c:Category) return c LIMIT 5;

图视图是

import guide Categories

表视图包含这些节点属性值

c

{"description":Soft drinks, coffees, teas, beers, and ales,"categoryName":Beverages,"categoryID":1}

{"description":Sweet and savory sauces, relishes, spreads, and seasonings,"categoryName":Condiments,"categoryID":2}

{"description":Desserts, candies, and sweet breads,"categoryName":Confections,"categoryID":3}

{"description":Cheeses,"categoryName":Dairy Products,"categoryID":4}

{"description":Breads, crackers, pasta, and cereal,"categoryName":Grains/Cereals,"categoryID":5}

对于非常大的商业或企业数据集,您可能会遇到内存溢出错误,特别是在小型机器上。为了避免这种情况,您可以使用 CALL IN {…​} TRANSACTIONS 子查询来分批提交数据。别忘了在 Neo4j 浏览器中为此查询添加 :auto 前缀。这种做法对于较小的数据集不是标准建议,仅在有内存问题风险时才推荐使用。有关此子查询的更多信息,请参阅 Cypher 手册 → 事务中的子查询。

为图中的数据创建索引和约束

创建节点后,您需要创建它们之间的关系。导入关系意味着查找您刚刚创建的节点,并在这些现有实体之间添加关系。为了确保节点查找得到优化,您需要为查找中使用的任何节点属性(通常是 ID 或其他唯一值)创建索引。

我们还想创建一个约束(同时也创建了一个索引),以防止创建具有相同 ID 的订单,从而避免重复。最后,由于索引是在插入节点后创建的,它们的填充是异步发生的,因此我们调用 db.awaitIndexes() 进行阻塞,直到它们完成填充。

执行此代码块

CREATE INDEX product_id FOR (p:Product) ON (p.productID);
CREATE INDEX product_name FOR (p:Product) ON (p.productName);
CREATE INDEX supplier_id FOR (s:Supplier) ON (s.supplierID);
CREATE INDEX employee_id FOR (e:Employee) ON (e.employeeID);
CREATE INDEX category_id FOR (c:Category) ON (c.categoryID);
CREATE CONSTRAINT order_id FOR (o:Order) REQUIRE o.orderID IS UNIQUE;
CALL db.awaitIndexes();

执行此代码后,您可以运行以下 Cypher 命令来查看数据库中的索引

SHOW INDEXES;

创建 Neo4j 数据库时,默认存在两个标记查找索引(一个用于节点标签,一个用于关系类型)。它们专门解决节点标签和关系类型谓词,并辅助填充其他索引。删除它们可能会对性能产生负面影响。您应该在数据库中看到这些索引(和约束)

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|id|name          |state |populationPercent|type  |entityType  |labelsOrTypes|properties   |indexprovider   |owningConstraint|lastRead                      |readCount|
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|7 |category_id   |ONLINE|100.0            |RANGE |NODE        |[Category]   |[categoryID] |range-1.0       |null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|6 |employee_id   |ONLINE|100.0            |RANGE |NODE        |[Employee]   |[employeeID] |range-1.0       |null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|1 |index_343aff4e|ONLINE|100.0            |LOOKUP|NODE        |null         |null         |token-lookup-1.0|null            |2023-12-06T12:30:12.510000000Z|2286     |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|2 |index_f7700477|ONLINE|100.0            |LOOKUP|RELATIONSHIP|null         |null         |token-lookup-1.0|null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|8 |order_id      |ONLINE|100.0            |RANGE |NODE        |[Order]      |[orderID]    |range-1.0       |order_id        |2023-12-06T13:22:06.950000000Z|3815     |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|3 |product_id    |ONLINE|100.0            |RANGE |NODE        |[Product]    |[productID]  |range-1.0       |null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|4 |product_name  |ONLINE|100.0            |RANGE |NODE        |[Product]    |[productName]|range-1.0       |null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|5 |supplier_id   |ONLINE|100.0            |RANGE |NODE        |[Supplier]   |[supplierID] |range-1.0       |null            |null                          |0        |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+

有关索引及其在 Neo4j 中使用的更多信息,请转至 Cypher 手册 → 索引的使用。

创建节点之间的关系

接下来您必须创建关系

  1. 在 Orders 和 Employees 之间。

  2. 在 Products 和 Suppliers 之间,以及 Products 和 Categories 之间。

  3. 在 Employees 之间。

创建 Orders 和 Employees 之间的关系

在初始节点和索引就位后,您现在可以创建订单到产品以及订单到员工的关系。

执行此代码块

// Create relationships between orders and products
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (product:Product {productID: row.ProductID})
MERGE (order)-[op:CONTAINS]->(product)
  ON CREATE SET op.unitPrice = toFloat(row.UnitPrice), op.quantity = toFloat(row.Quantity);

此代码在图中创建了 2155 个关系。

您可以通过执行此代码查看其中的一些关系

MATCH (o:Order)-[]-(p:Product)
RETURN o,p LIMIT 10;

您的图视图应该看起来像这样

import guide CONTAINS

然后,执行此代码块

// Create relationships between orders and employees
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/orders.csv' AS row
MATCH (order:Order {orderID: row.OrderID})
MATCH (employee:Employee {employeeID: row.EmployeeID})
MERGE (employee)-[:SOLD]->(order);

此代码在图中创建了 830 个关系。

您可以通过执行此代码查看其中的一些关系

MATCH (o:Order)-[]-(e:Employee)
RETURN o,e LIMIT 10;

您的图视图应该看起来像这样

import guide SOLD

创建 Products 和 Suppliers 之间以及 Products 和 Categories 之间的关系

接下来,在 Products、Suppliers 和 Categories 之间创建关系

执行此代码块

// Create relationships between products and suppliers
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv
' AS row
MATCH (product:Product {productID: row.ProductID})
MATCH (supplier:Supplier {supplierID: row.SupplierID})
MERGE (supplier)-[:SUPPLIES]->(product);

此代码在图中创建了 77 个关系。

您可以通过执行此代码查看其中的一些关系

MATCH (s:Supplier)-[]-(p:Product)
RETURN s,p LIMIT 10;

您的图视图应该看起来像这样

import guide SUPPLIES

然后,执行此代码块

// Create relationships between products and categories
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/products.csv
' AS row
MATCH (product:Product {productID: row.ProductID})
MATCH (category:Category {categoryID: row.CategoryID})
MERGE (product)-[:PART_OF]->(category);

此代码在图中创建了 77 个关系。

您可以通过执行此代码查看其中的一些关系

MATCH (c:Category)-[]-(p:Product)
RETURN c,p LIMIT 10;

您的图视图应该看起来像这样

import guide PART OF

创建 Employees 之间的关系

最后,您将在 Employees 之间创建“REPORTS_TO”关系,以表示报告结构

执行此代码块

// Create relationships between employees (reporting hierarchy)
LOAD CSV WITH HEADERS FROM 'https://gist.githubusercontent.com/jexp/054bc6baf36604061bf407aa8cd08608/raw/8bdd36dfc88381995e6823ff3f419b5a0cb8ac4f/employees.csv' AS row
MATCH (employee:Employee {employeeID: row.EmployeeID})
MATCH (manager:Employee {employeeID: row.ReportsTo})
MERGE (employee)-[:REPORTS_TO]->(manager);

此代码在图中创建了 8 个关系。

您可以通过执行此代码查看其中的一些关系

MATCH (e1:Employee)-[]-(e2:Employee)
RETURN e1,e2 LIMIT 10;

您的图视图应该看起来像这样

import guide REPORTS TO

接下来,您将查询生成的图,看看它能告诉我们关于我们新导入的数据的什么信息。

查询图数据

我们可以先运行几个常规查询,以验证我们的数据是否符合我们在指南前面设计的模型。以下是一些示例查询。

执行此代码块

//find a sample of employees who sold orders with their ordered products
MATCH (e:Employee)-[rel:SOLD]->(o:Order)-[rel2:CONTAINS]->(p:Product)
RETURN e, rel, o, rel2, p LIMIT 25;

执行此代码块

//find the supplier and category for a specific product
MATCH (s:Supplier)-[r1:SUPPLIES]->(p:Product {productName: 'Chocolade'})-[r2:PART_OF]->(c:Category)
RETURN s, r1, p, r2, c;

一旦您确信数据符合我们的数据模型并且看起来一切正确,您就可以开始查询以收集信息并洞察业务决策。

哪位员工在“Chocolade”和其他产品的交叉销售次数最高?

执行此代码块

MATCH (choc:Product {productName:'Chocolade'})<-[:CONTAINS]-(:Order)<-[:SOLD]-(employee),
      (employee)-[:SOLD]->(o2)-[:CONTAINS]->(other:Product)
RETURN employee.employeeID as employee, other.productName as otherProduct, count(distinct o2) as count
ORDER BY count DESC
LIMIT 5;

看起来 4 号员工很忙,尽管 1 号员工也做得不错!您的结果应该看起来像这样

employee otherProduct count

4

Gnocchi di nonna Alice

14

4

Pâté chinois

12

1

Flotemysost

12

3

Gumbär Gummibärchen

12

1

Pavlova

11

员工是如何组织的?谁向谁汇报?

执行此代码块

MATCH (e:Employee)<-[:REPORTS_TO]-(sub)
RETURN e.employeeID AS manager, sub.employeeID AS employee;

您的结果应该看起来像这样

manager employee

2

3

2

4

2

5

2

1

2

8

5

9

5

7

5

6

请注意,5 号员工既有向他们汇报的人,也向 2 号员工汇报。

接下来,让我们深入调查一下。

哪些员工间接向彼此汇报?

执行此代码块

MATCH path = (e:Employee)<-[:REPORTS_TO*]-(sub)
WITH e, sub, [person in NODES(path) | person.employeeID][1..-1] AS path
RETURN e.employeeID AS manager, path as middleManager, sub.employeeID AS employee
ORDER BY size(path);

您的结果应该看起来像这样

manager middleManager employee

2

[]

3

2

[]

4

2

[]

5

2

[]

1

2

[]

8

5

[]

9

5

[]

7

5

[]

6

2

[5]

9

2

[5]

7

2

[5]

6

等级制度的每一部分完成了多少订单?

执行此代码块

MATCH (e:Employee)
OPTIONAL MATCH (e)<-[:REPORTS_TO*0..]-(sub)-[:SOLD]->(order)
RETURN e.employeeID as employee, [x IN COLLECT(DISTINCT sub.employeeID) WHERE x <> e.employeeID] AS reportsTo, COUNT(distinct order) AS totalOrders
ORDER BY totalOrders DESC;

您的结果应该看起来像这样

employee reportsTo totalOrders

2

[8,1,5,6,7,9,4,3]

830

5

[6,7,9]

224

4

[]

156

3

[]

127

1

[]

123

8

[]

104

7

[]

72

6

[]

67

9

[]

43

接下来做什么?

如果您按照本指南的每个步骤操作,那么您可能需要通过更多查询来探索数据集,并尝试回答您为数据提出的其他问题。您还可以将这些相同的原则应用于您自己或其他数据集进行分析。

如果您将此作为流程来应用于不同的数据集,或者想接下来这样做,请随时从头开始,并使用另一个领域再次研读本指南。步骤和流程仍然适用(当然,数据模型、查询和业务问题需要相应调整)。

如果您拥有的数据需要比本指南所涵盖的内容更多的清洗和操作,APOC 库可能会有所帮助。它包含数百个过程和函数,用于处理大量数据、转换值、清理混乱的数据源等等!

如果您有兴趣将关系数据一次性初始导入到 Neo4j,那么 Neo4j ETL 工具可能是您正在寻找的。该应用程序采用点击式用户界面设计,旨在实现快速、简单的关系到图的加载,帮助新老用户在无需 Cypher、导入过程或其他代码的情况下,通过将数据视为图而获得更快的价值。

资源

© . This site is unofficial and not affiliated with Neo4j, Inc.