Neo4j 驱动 API

Neo4j 驱动导出一个统一的 API。这使得驱动概念和命名可以在不同生态系统之间共享,从而使语言之间的转换和多语言支持变得更简单、更一致。

驱动对象

  • 驱动

  • 会话

  • 事务

  • DriverConfig

    • uri::String

    • auth::Dictionary

    • user_agent::String

    • encrypted::Boolean

    • trust::String

  • SessionConfig

    • default_access_mode::String

    • database::String

    • fetch_size::Integer

    • bookmarks::List<String>

    • imp_user::String

  • TransactionConfig

    • metadata::Dictionary

    • timeout::Integer

  • AuthToken

  • 事务管理器

  • 连接池

  • 路由

  • Bolt 协议

  • PackStream

  • Neo4j 异常

  • 驱动异常

URI 方案

未启用 TLS

  • bolt: 连接到单个 Neo4j 实例。

  • neo4j: 连接到 Neo4j 实例并使用路由表信息进行后续连接。

启用 TLS 并允许自签名证书颁发机构

  • bolt+ssc

  • neo4j+ssc

启用 TLS 并仅允许系统启用的证书颁发机构及验证主机名

  • bolt+s

  • neo4j+s

客户端路由

Neo4j 支持集群设置并使用 Raft 共识算法

集群中的每个 Neo4j 服务器都支持路由读取。集群中只有一个主服务器可以被选为领导者,负责写入操作。此选择会随时间轮换。驱动程序应支持一个路由表服务器不参与 Raft 共识算法,但从服务器会返回一个只包含从服务器本身的路由表。

有关更多信息,请参阅操作手册 → 集群

获取路由表

在 Neo4j 的各个版本中,获取路由表的存储过程调用发生了很大变化。

表 1. 路由消息 (4.3+)
Neo4j Bolt Bolt 消息

4.3

4.3

ROUTE {$context} [$bookmarks] $db

4.4

4.4

ROUTE {$context} [$bookmarks] {"db": $db, "imp_user": $imp_user}

表 2. 如何获取数据库 foo 的路由表
Neo4j Bolt Bolt 消息

4.3

4.3

ROUTE {"address": "example.org:7687"} ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"] "foo"

4.4

4.4

ROUTE {"address": "example.org:7687"} ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"] {"db": "foo"}

示例
C: 60 60 B0 17
C: 00 00 04 04 00 00 00 00 00 00 00 00 00 00 00 00
S: 00 00 04 04
C: HELLO {"scheme": "basic", "principal": "user", "credentials": "password", "user_agent": "Example/4.4.0", "routing": {"address": "localhost:9001", "policy": "example_policy", "region": "example_region"}}
S: SUCCESS {"server": "Neo4j/4.4.0", "connection_id": "bolt-123456789"}
C: ROUTE {"address": "localhost:9001", "policy": "example_policy", "region": "example_region"} ["neo4j-bookmark-transaction:1", "neo4j-bookmark-transaction:2"], {}
S: SUCCESS {"rt": {"ttl": 300, "db": "foo", "servers": [{"addresses": ["127.0.0.1:9001"], "role": "WRITE"}, {"addresses": ["127.0.0.1:9002"], "role": "READ"}, {"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "ROUTE"}]}}
C: GOODBYE

存储过程调用 <4.2

Neo4j Bolt Neo4j 存储过程调用

3.5

3

dbms.cluster.routing.getRoutingTable($context)

4.0

4.0

dbms.routing.getRoutingTable($context, $database)

4.1

4.1

dbms.routing.getRoutingTable($context, $database)

4.2

4.2

dbms.routing.getRoutingTable($context, $database)

表 3. 如何获取数据库 foo 的路由表
Neo4j Bolt Bolt 消息

3.5

3

RUN "CALL dbms.cluster.routing.getRoutingTable($context)" {"context": {}} {"mode": "r"}

4.0

4.0

RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {}, "database": "foo"} {"db": "system", "mode": "r"}

4.1

4.1

RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {}, "database": "foo"} {"db": "system", "mode": "r"}

4.2

4.2

RUN "CALL dbms.routing.getRoutingTable($context, $database)" {"context": {}, "database": "foo"} {"db": "system", "mode": "r"}

示例
C: 60 60 B0 17
C: 00 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00
S: 00 00 01 04
C: HELLO {"scheme": "basic", "principal": "user", "credentials": "password", "user_agent": "Example/4.1.0", "routing": {"address": "localhost:9001", "policy": "example_policy", "region": "example_region"}}
S: SUCCESS {"server": "Neo4j/4.1.0", "connection_id": "bolt-123456789"}
C: RUN "CALL dbms.routing.getRoutingTable($context)" {"context": {"address": "localhost:9001", "policy": "example_policy", "region": "example_region"}} {"mode": "r", "db": "system"}
C: PULL {"n": -1}
S: SUCCESS {"fields": ["ttl", "servers"]}
S: RECORD [300, [{"addresses": ["127.0.0.1:9001"], "role": "WRITE"}, {"addresses": ["127.0.0.1:9002"], "role": "READ"}, {"addresses": ["127.0.0.1:9001", "127.0.0.1:9002"], "role": "ROUTE"}]]
S: SUCCESS {"bookmark": "example-bookmark:1", "type": "r", "t_last": 5, "db": "system"}
C: GOODBYE

集群与多数据库

系统数据库

  • 系统数据库的名称是固定的,命名为 system

  • 对于单个实例或集群,系统数据库不可更改。

  • 系统数据库存在于每个实例上。

集群成员

一个集群包含成员和成员。

  • 任何时候只有一个主成员可以是领导者(接受写入)。

  • 集群中的每个数据库都有自己的 Raft 组,并且每个数据库都有自己的路由表。换句话说,集群中每个数据库的领导者/主/从可以是不同的。

  • 集群中的任何主成员都可以为该集群内的任何数据库提供路由表。给定指向主成员的种子 URL,这可用于通过从主成员获取路由表来查找集群中的任何数据库。

此外,在 Neo4j 4.x 中

  • 每个集群成员都托管完全相同的数据库。如果集群成员 A 拥有数据库 foosystem,那么所有其他集群成员也应该只拥有 foosystem

  • 单个实例和/或集群有一个默认数据库。

这些不适用于 Neo4j 5.x。

驱动路由表

驱动程序应防止路由表无限增长。如果尝试获取路由信息失败,应从路由表中删除特定数据库的路由表。如果路由表无效,则应从路由表中删除特定数据库的路由表。无效的路由表可能是:

  • 已超时的路由表,即该路由表的 TTL(生存时间)键已过期。

  • 指向不再存在的数据库的路由表。

这是驱动程序在获取名为 foo 的数据库路由表时应遵循的工作流程。

  1. 查找数据库 foo 的路由表。

  2. 如果数据库在路由表中不存在,则创建一个以种子 URL 作为初始路由器的空路由表。

  3. 如果路由表过时,则向集群成员发送查询以刷新路由表。

  4. 如果发生任何错误,从路由表映射中移除键 foo

唯一可能发生的错误是:

  • SECURITY_ERROR

  • ROUTING_ERROR

  • SERVICE_UNAVAILABLE_ERROR,当驱动程序无法获取所有现有路由器的路由表时发生。

客户端日志记录

  • 日志级别

  • 日志语法

会话

  • 连接

  • 连接池

事务

  • 原子工作单元

  • 事务管理器

  • 事务函数

因果链

  • 书签

© . All rights reserved.