Neo4j导入数据的5种方式详解配图

一、前言

Neo4j导入数据的方式有:

  1. 使用LOAD CSV导入数据
  2. 使用APOC导入数据
  3. 使用编程语言(Java,python,js,C#,Go)导入数据
  4. 使用neo4j-admin工具导入数据
  5. 使用应用导入数据
  6. 使用ETL工具导入数据

具体选择哪种导入方法取决于:

  1. 数据量大小
  2. 使用者对导入方法的轻松度感受
  3. 有多少时间来导入
    各种导入方法的精力-效率图像如下图:
    Neo4j导入数据的5种方式详解配图_第1张图片
    横坐标表示导入的效率,LOAD CSV导入比较慢,而neo4j-admin工具导入比较快。
    纵坐标表示人耗费的精力,LOAD CSV比较易上手,而使用编程语言如Java/Python等导入数据比较耗费精力。

二、使用LOAD CSV来导入数据

CSV格式的数据是文本数据,数据之间用英文逗号隔开。
支持的数据类型:仅CSV
好处:操作简单。
坏处:运行时间长
Neo4j导入数据的5种方式详解配图_第2张图片
关键步骤就是:先生成CSV文件,然后用Cypher语句“LOAD CSV”将数据导入到Neo4j数据库中。
这种方式是最简单的导入数据到neo4j的方式,也是广泛使用来导入原始数据。
使用LOAD CSV导入数据的要求

  1. CSV文件已经备好
  2. Neo4j Browser或Cypher-shell已打开,Neo4j DBMS在本地运行,或Aura,或Sandbox
  3. 可选(不是必须):在Neo4j集群上
  4. 如果大于100K行数据,则需要特殊处理

用Cypher加载数据的步骤

  1. CSV文件组织结构
  2. 规范化数据
  3. 确保ID唯一
  4. 确保CSV中的数据是干净的
  5. 执行Cypher代码来检查数据
  6. 确定数据是否需要转化
  7. 确保有必要的数据约束
  8. 确定加载数据量的大小
  9. 执行Cypher代码来加载数据
    10.为图数据添加索引

(1)CSV文件结构
Neo4j导入数据的5种方式详解配图_第3张图片
CSV文件包括header和data两部分,当数据量较大且有多个files时,建议将header与data分离开。
(2)规范化数据
Neo4j导入数据的5种方式详解配图_第4张图片
people.csv表示演员表,movies1.csv表示电影表,roles.csv表示演员参演电影表,这时候可以将roles在图数据库中的关系规范化为*:ACTED_IN*
(3)ID必须唯一
(4)数据干净吗?

  • 检查header与对应数据列是否匹配
  • 数据参照是否正确
  • 空值是用“”还是NULL
  • 数据格式,UTF-8
  • 有些字段有尾随空格吗?
  • 字段是否包含二进制零
  • 了解列表是如何形成的,默认是冒号(:)作为分隔符
  • 逗号(:)是分隔符吗?
  • 有明显的打字错误吗?
    (5)执行Cypher来检验数据
LOAD CSV WITH HEADERS
FROM 'https://data.neo4j.com/v4.0-intro-neo4j/people.csv'
AS line
WITH line WHERE line.birthYear > "1999"
RETURN line LIMIT 10

Neo4j导入数据的5种方式详解配图_第5张图片

(6)确定是否需要转化
在这里插入图片描述
无论什么数据,导入到neo4j中都视为字符串,因此导入时可以预先进行转换。
(7)确定数据约束
一般主键id需要有唯一性约束。下面例子是为Movie和Person分别为id建立唯一性约束。

CREATE CONSTRAINT UniqueMovieIdConstraint ON (m:Movie) ASSERT m.id IS UNIQUE;

CREATE CONSTRAINT UniquePersonIdConstraint ON (p:Person) ASSERT p.id IS UNIQUE

创建结点有MERGE和CREATE两种方式,MERGE比CREATE多了检查唯一性。
(8)确定加载数据量的大小
LOAD CSV这种方式只能加载100K的数据量。
若超出100K的csv文件,有两种方式解决:

  1. :auto USING PERIODIC COMMIT
  2. 使用APOC,下一节
    第一种方式相当于分批次插入数据,例如每次插入1000条。但是遇到eager类型的聚合函数方法时,第一种方式会失效,eager类型的聚合函数有:collect(), count(), order by, distinct,这时候只能使用第二种方式。
    (9)执行Cypher代码来加载数据
    a. 导入电影结点
:auto USING PERIODIC COMMIT 500  #每次循环插入500个结点
LOAD CSV WITH HEADERS FROM
  'https://data.neo4j.com/v4.0-intro-neo4j/movies1.csv' as row
MERGE (m:Movie {id:toInteger(row.movieId)})
    ON CREATE SET
          m.title = row.title,
          m.avgVote = toFloat(row.avgVote),
          m.releaseYear = toInteger(row.releaseYear),
          m.genres = split(row.genres,":")

b. 导入演员结点

:auto USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM
  'https://data.neo4j.com/v4.0-intro-neo4j/people.csv' as row
MERGE (p:Person {id:toInteger(row.personId)})
    ON CREATE SET
          p.name=row.name,
          p.birthYear=toInteger(row.birthYear),
          p.deathYear=toInteger(row.deathYear)

c. 导入“导演”关系

LOAD CSV WITH HEADERS FROM
'https://data.neo4j.com/v4.0-intro-neo4j/directors.csv' AS row
MATCH (movie:Movie {id:toInteger(row.movieId)})
MATCH (person:Person {id: toInteger(row.personId)})
MERGE (person)-[:DIRECTED]->(movie)
ON CREATE SET person:Director

(10)为图数据添加索引

CREATE INDEX MovieTitleIndex FOR (m:Movie) ON (m.title);
CREATE INDEX PersonNameIndex FOR (p:Person) ON (p.name)

三、使用APOC数据

支持数据格式:CSV,XML,GraphXML,JSON
使用APOC导入数据的要求:

  1. CSV,XML,或JSON文件已备好
  2. Neo4j Browser或Cypher-shell已打开,Neo4j DBMS在本地运行,或Aura,或Sandbox
  3. 可选(不是必须):在Neo4j集群上
  4. 对导入数据集大小没有限制

四、使用编程语言导入数据

Neo4j导入数据的5种方式详解配图_第6张图片
编程语言-驱动-Neo4j的方式来导入数据。
使用驱动导入数据的要求:

  1. Neo4j Browser或Cypher-shell已打开,Neo4j DBMS在本地运行,或Aura,或Sandbox
  2. 可选(不是必须):在Neo4j集群上
  3. 运行中的RDBMS服务器
  4. 负责事务作用域的应用程序,即编程语言
  5. 对导入数据量大小无限制
  6. 支持Java、Python、Javascript、C#等,仅有Java和C#支持异步
    -1- Java语言
		<dependency>
            <groupId>org.neo4j.drivergroupId>
            <artifactId>neo4j-java-driverartifactId>
            <version>4.2.0version>
        dependency>

import org.neo4j.driver.*;

import static org.neo4j.driver.Values.parameters;

public class HelloWorldExample implements AutoCloseable {
    private final Driver driver;

    public HelloWorldExample(String uri, String user, String password) {
        driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
    }

    @Override
    public void close() throws Exception {
        driver.close();
    }

    public void printGreeting(final String message) {
        try (Session session = driver.session()) {
            String greeting = session.writeTransaction(new TransactionWork<String>() {
                @Override
                public String execute(Transaction tx) {
                    Result result = tx.run("CREATE (a:Greeting) " +
                                    "SET a.message = $message " +
                                    "RETURN a.message + ', from node ' + id(a)",
                            parameters("message", message));

                    return result.single().get(0).asString();
                }
            });
            System.out.println(greeting);
        }
    }

    public void syn() {
        try (Session session = driver.session()) {
            session.readTransaction(new TransactionWork<String>() {
                @Override
                public String execute(Transaction tx) {
                    Result result=tx.run("MATCH (a:Person) RETURN a.name limit 10");
                    while(result.hasNext()) {
                        Record record = result.next();
                        System.out.println(record.get("a.name"));
                    }
                    return null;
                }
            });
        }


    }

    public static void main(String... args) throws Exception {
        try (HelloWorldExample greeter = new HelloWorldExample("bolt://localhost:11005", "neo4j", "123456")) {
//            greeter.printGreeting("你好,世界");
            greeter.syn();
        }
    }
}

-2- Python语言

pip install neo4j
from neo4j import GraphDatabase

class HelloWorldExample:

    def __init__(self, uri, user, password):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))

    def close(self):
        self.driver.close()

    def print_greeting(self, message):
        with self.driver.session() as session:
            greeting = session.write_transaction(self._create_and_return_greeting, message)
            print(greeting)

    @staticmethod
    def _create_and_return_greeting(tx, message):
        result = tx.run("CREATE (a:Greeting) "
                        "SET a.message = $message "
                        "RETURN a.message + ', from node ' + id(a)", message=message)
        return result.single()[0]


if __name__ == "__main__":
    greeter = HelloWorldExample("bolt://localhost:7687", "neo4j", "password")
    greeter.print_greeting("hello, world")
    greeter.close()

五、使用neo4j-admin工具导入数据

支持的数据格式:仅CSV,只能在Desktop端使用,Sandbox和Aura不支持使用该工具。
好处:导入时间少,效率高,支持导入数据很大(如超过10M),一次性导入多个CSV文件
缺点:neo4j数据库必须在导入完成后才能使用
Neo4j导入数据的5种方式详解配图_第7张图片
使用neo4j-admin工具导入数据的要求:

  1. CSV文件已备好
  2. Neo4j DBMS在本地运行,不支持Sandbox和Aura
  3. 无数据量大小限制
    -1- 导入结点
    (1)包含头信息的文件
    id,结点类型
    在这里插入图片描述
    (2)或将头信息与数据存储在不同csv文件上
    id,结点类型,日期,描述
    在这里插入图片描述
    Neo4j导入数据的5种方式详解配图_第8张图片
    -2- 导入关系
    开始结点id,结束结点id,关系类型
    Neo4j导入数据的5种方式详解配图_第9张图片
    -3- 指定对应结点的首个Label
    一个node可能有多个Label,如一个罪犯有多种罪名,选取一个主要罪名。
    罪名列表Labels:
    Neo4j导入数据的5种方式详解配图_第10张图片
    罪犯首要罪名:
    Neo4j导入数据的5种方式详解配图_第11张图片
    -4- 导入语法
neo4j-admin import
  database <database-name>
  nodes [<rheader-csv-file-1>,]<csv-file-1>
  nodes=<Label>=[<rheader-csv-file-2>,]<csv-file-2>
  relationships [<jheader-csv-file-1>,]<join-csv-file-1>
  relationships=<REL_TYPE>=[<jheader-csv-file-2>,]<join-csv-file-2>
  trim-strings=true
  > import.out

六、使用ETL工具导入数据

能够实现DBMS和neo4j之间的实时连接来导入数据。
Neo4j导入数据的5种方式详解配图_第12张图片
使用ETL工具导入数据的要求:

  1. 已安装并打开ETL工具
  2. Neo4j DBMS在本地运行,或Aura,或Sandbox
  3. 可选,使用Neo4j集群
  4. 运行中的RDBMS服务器
  5. 无数据量大小限制

导入步骤:

  1. 确保dbms在运行,在desktop打开了ETL工具
  2. 指定目标图数据库,因为一个neo4j dbms可以有多个图数据库
  3. 指定和测试RDBMS的连接
  4. 准备映射
  5. 查看要执行的默认映射,也可以修改映射
  6. 保存映射
  7. 导入数据

七、总结

在这里插入图片描述

你可能感兴趣的:(neo4j,neo4j)