GDB Cypher:Cypher用户的最佳选择

Neo4J 是DB-Engines图数据领域长期排名第一的数据库产品,目前有社区版和企业版两个版本:

• 社区版:单实例、无容灾、不支持热备、缺乏技术支撑
• 企业版:高性能、可扩展、高可用、多种安全级别、数据完整性、完全托管、丰富的监控&审计

企业版目前最便宜的4Core单实例一年价格将近30万,高昂的价格让国内中小企业望而却步。目前国内大部分用户都选择社区版并在上面做定制开发,这需要企业投入额外人力成本进行图数据自管理和运营。下面是Neo4j企业版和Gdb云产品不同规格的价格对比:
GDB Cypher:Cypher用户的最佳选择

兼容性

既然想要接入Gdb,那么Gdb目前Cypher支持到什么程度了?是否可以满足业务的使用需求?
目前Gdb Cypher只支持bolt-v3协议;数据类型上目前支持Temporal外所有的数据类型,子句上基本支持所有常用的子句,函数上除过一些算数方法外基本也支持所有常用的函数,Procedure目前只支持少量的场景;Gdb相比Neo4j 4.0的差异主要提现在多图、索引、导入导出、可视化等方面;Sessions目前支持常见的同步异步两种模式。

数据类型

GDB Cypher:Cypher用户的最佳选择

子句/函数

GDB Cypher:Cypher用户的最佳选择

Neo4j差异性

GDB Cypher:Cypher用户的最佳选择

接入方式

业务觉得目前支持的Cypher场景已经足够接入,那么想接入Gdb,该怎么接入呢?

数据导入

假定数据可以在Neo4j社区版中,首先利用apoc导出为graphml格式,其次利用GraphML2CSV转为CSV格式,然后将CSV文件上传到OSS中,最后通过Gdb命令将OSS文件导入到Gdb中。
GDB Cypher:Cypher用户的最佳选择

存量数据已经导入到Gdb中了,怎么插入新的数据?怎么查询存储数据?这里就需要通过客户端Driver来接入了。
官方4.0版本目前提供包括 Java, .Net, JavaScript三种接入形式,另外Go, Python正在开发中。 Gdb目前主要支持Java、 .Net两个版本。以Java Driver为例,目前按业务需求可以支持两种接入形态:

Java Driver

• 依赖

<dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>4.0.0</version>
</dependency>

• 初始化

public Demo() {
    String uri = "bolt://server-domain:server-port";
    String username = "your-gdb-username";
    String password = "your-gdb-password"
    Logging logging = new ConsoleLogging(FINE);
    Config config = Config.builder()
        .withLogging(logging)
        .withMaxConnectionLifetime(30, TimeUnit.MINUTES)
        .withMaxConnectionPoolSize(50)
        .withConnectionAcquisitionTimeout(2, TimeUnit.MINUTES)
        .build();
    private  Driver driver = GraphDatabase.driver(uri, 
         AuthTokens.basic(username, password), config);
}

• Simple Sessions

public void simpleSessions(final String dsl, final Map<String, Object> args) {
    try (Session session = driver.session()) {
        ///1. Transaction functions
        session.writeTransaction(tx -> {
            StringBuilder buffer = new StringBuilder();
            Result result = tx.run(dsl, args);
            result.stream().forEach(t -> 
                System.out.println(output(t)));
            return buffer.toString();
        });
        ///2. Auto-commit Transactions tested
        {
            Result result = session.run(dsl, args);
            result.stream().forEach(t -> 
                System.out.println(output(t)));
        }
    }
}

• Async Sessions

public void asyncSample(final String dsl, final Map<String, Object> args) {
    AsyncSession session = driver.asyncSession();
    ///1.  Transaction functions
    session.readTransactionAsync(tx ->
        tx.runAsync(dsl, args)
            .thenCompose(cursor -> cursor.forEachAsync(record ->
                System.out.println("asyncTransactionFuctions - " + record.get(0))))
    );
    ///2. Auto-commit Transactions tested
    session.runAsync(dsl, args)
        .thenCompose(cursor -> cursor.forEachAsync(record ->
            System.out.println("asyncAutoTransactions - " + record.get(0))));
}
Spring Data Neo4j
• 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>

• 配置环境
修改src/main/resources/application.properties文件,配置域名、用户名、密码

• 测试
这里提供了一个Movie-Actor的Sample可以作为学习教程
恭喜您!到了这里,您已经可以顺利将Cypher数据导入Gdb,并根据业务具体场景进行简单的添加、查询、更新、删除了。可能使用中会碰到一些小的困惑,下面的Tips或许可以提供一些帮助:

最佳实践

• 参数化
用户请求基本上一般只有几种场景,参数化把每种类型的翻译结果进行缓存,从而加速语句的执行时解析,比如

• Parameters:
{
  "name" : "Michael"
}

• Query:

MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name

• 设置线程池的大小
在初始化Neo4j的Driver时,需要配置MaxConnectionPoolSize、ConnectionTimeout、MaxConnectionLifetime等参数,这样能充分利用线程池、并且控制连接的生命周期,更多的配置参考这里

• 删除时限制大小
由于Gdb对事务Buffer的大小限制为64M,如果一次删除的数据量过大可能导致事务无法成功,建议通过LIMIT限制数据集

MATCH (n) LIMIT 1024 DETACH DELETE n;

• 关于Bolt协议
目前Neo4j 4.0最新的Bolt协议为V4,Gdb Server目前提供的最低版本为Bolt V3,建议Java driver使用版本为:4.0.0或者2.0.0-alpha01。

参考

1. Neo4j企业版能力
2. Neo4j企业版价格
3, Neo4j Cypher Manual 4.0
4. Neo4j Driver列表

上一篇:耗时又繁重的SQL诊断优化,以后就都交给数据库自治服务DAS吧!


下一篇:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[扩展篇]