anyitsolutions / neo4j-php-client
Requires
- php: ^7.0
- ext-bcmath: *
- ext-mbstring: *
- anyitsolutions/neo4j-bolt: ^1.12
- graphaware/neo4j-common: ^3.4
- myclabs/php-enum: ^1.4
- php-http/client-common: ^1.0
- php-http/discovery: ^1.0
- php-http/guzzle6-adapter: ^1.0
- php-http/httplug: ^1.0
- php-http/message: ^1.0
- php-http/message-factory: ^1.0
- symfony/event-dispatcher: ^4.0 || ^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.0
- phpunit/phpunit: ^4.0
- symfony/stopwatch: ^3.0
- dev-master
- 4.8.8
- 4.8.7
- 4.8.6
- 4.8.5
- 4.8.4
- 4.8.3
- 4.8.2
- 4.8.1
- 4.8.0
- 4.7.0
- 4.6.4
- 4.6.3
- 4.6.2
- 4.6.1
- 4.6.0
- 4.5.5
- 4.5.4
- 4.5.3
- 4.5.2
- 4.5.1
- 4.5.0
- 4.4.7
- 4.4.6
- 4.4.5
- 4.4.4
- 4.4.3
- 4.4.2
- 4.4.1
- 4.4.0
- 4.3.1
- 4.3.0
- 4.2.1
- 4.2.0
- 4.1.1
- 4.1.0
- 4.0.x-dev
- 4.0.2
- 4.0.1
- 4.0.0
- 4.0.0-alpha15
- 4.0.0-alpha14
- 4.0.0-alpha13
- 4.0.0-alpha12
- 4.0.0-alpha11
- 4.0.0-alpha10
- 4.0.0-alpha9
- 4.0.0-alpha8
- 4.0.0-alpha7
- 4.0.0-alpha6
- 4.0.0-alpha5
- 4.0.0-alpha4
- 4.0.0-alpha3
- 4.0.0-alpha2
- 4.0.0-alpha1
- 3.4.x-dev
- 3.4.2
- 3.4.1
- 3.3.20
- 3.3.19
- 3.3.18
- 3.3.17
- 3.3.16
- 3.3.15
- 3.3.14
- 3.3.13
- 3.3.12
- 3.3.11
- 3.3.10
- 3.3.9
- 3.3.8
- 3.3.7
- 3.3.6
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.x-dev
- 3.0.2
- 3.0.1
- 3.0.0
- 2.2.10
- 2.2.9
- 2.2.8
- 2.2.7
- 2.2.6
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2
- 2.1.20
- 2.1.19
- 2.1.18
- 2.1.17
- 2.1.16
- 2.1.15
- 2.1.14
- 2.1.13
- 2.1.12
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1.x-dev
- 2.1.1
- 2.1.0
- 2.0.x-dev
- 2.0.11
- 2.0.10
- 2.0.9
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.7.x-dev
- 1.6.x-dev
- 1.6.9
- 1.6.8
- 1.6.7
- 1.6.6
- 1.6.5
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
- dev-ClaasBrueggemann-feature/v4-support
- dev-issue105-bis
- dev-issue-105
- dev-fix/empty-array
- dev-tx-events
- dev-issue40
- dev-ikwattro-patch-12
- dev-ikwattro-patch-11
- dev-ikwattro-patch-10
- dev-ikwattro-patch-9
- dev-ikwattro-patch-8
- dev-ikwattro-patch-7
- dev-ikwattro-patch-6
- dev-ikwattro-patch-5
- dev-ikwattro-patch-4
- dev-ikwattro-patch-3
- dev-ikwattro-patch-2
- dev-ikwattro-patch-1
- dev-log
- dev-preview
- dev-livetx-fix
- dev-schema
- dev-issue-stefan
- dev-ha-no-yaml
- dev-connected-nodes
- dev-data-table
- dev-rows
- dev-custom-headers
- dev-travis
- dev-changePassword
- dev-3.0-dev
- dev-prepared-transaction
- dev-relProp
- dev-auth2
- dev-restformat
- dev-rest
- dev-client-changes
- dev-path
- dev-txmanager
- dev-1.6-dev
- dev-1.5-dev
- dev-1.4-dev
This package is auto-updated.
Last update: 2024-01-08 05:57:00 UTC
README
Neo4j 企业级客户端
简介
Neo4j-PHP-Client 是最先进和灵活的 Neo4j PHP 客户端。
什么是 Neo4j?
Neo4j 是一个事务性的开源图数据库。图数据库通过连接数据结构管理数据,能够以非常便捷的方式表示任何类型的数据。信息存储在节点及其连接关系上,节点和关系都可以有任意属性。了解更多信息,请访问 什么是图数据库?
主要特性
- 支持多个连接
- Bolt 二进制协议支持
- 内置自动支持 Neo4j 企业 HA 主从模式,具有自动从节点回退功能
Neo4j 版本支持
版本 | 已测试 |
---|---|
<= 2.2.6 | 否 |
>= 2.2.6 | 是 |
2.2 | 是 |
2.3 | 是 |
3.0 + | 是 |
Neo4j 特性支持
特性 | 支持? |
---|---|
认证 | 是 |
远程 Cypher | 是 |
事务 | 是 |
高可用性 | 是 |
嵌入式 JVM 支持 | 否 |
二进制协议 | 是 |
要求
- PHP >= 5.6
- ext-bcmath
- ext-mbstring
- A Neo4j 数据库(最低版本 2.2.6)
获取帮助
您可以
- 在 StackOverflow 上提问
- 对于错误,请随时在 GitHub 上创建 新问题
实现
安装和基本使用
安装
将库添加到您的 composer 依赖项
composer require "graphaware/neo4j-php-client:^4.0"
需要 composer 自动加载器,通过提供连接别名和连接设置来配置您的连接
<?php require_once 'vendor/autoload.php'; use GraphAware\Neo4j\Client\ClientBuilder; $client = ClientBuilder::create() ->addConnection('default', 'http://neo4j:password@localhost:7474') // Example for HTTP connection configuration (port is optional) ->addConnection('bolt', 'bolt://neo4j:password@localhost:7687') // Example for BOLT connection configuration (port is optional) ->build();
您现在可以连接到您的数据库了。
注意:构建方法将处理配置设置并返回一个 Client
实例。
基本使用
发送 Cypher 查询
$client->run('CREATE (n:Person)');
带参数发送Cypher查询
$client->run('CREATE (n:Person) SET n += {infos}', ['infos' => ['name' => 'Ales', 'age' => 34]]);
读取结果
$result = $client->run('MATCH (n:Person) RETURN n'); // a result always contains a collection (array) of Record objects // get all records $records = $result->getRecords(); // get the first or (if expected only one) the only record $record = $result->getRecord();
一个Record
对象包含Cypher查询中的一个记录的值
$query = 'MATCH (n:Person)-[:FOLLOWS]->(friend) RETURN n.name, collect(friend) as friends'; $result = $client->run($query); foreach ($result->getRecords() as $record) { echo sprintf('Person name is : %s and has %d number of friends', $record->value('name'), count($record->value('friends'))); }
Cypher语句和堆栈
理想情况下,您应该堆叠您的语句并一次性发出它们以提高性能。
您可以创建Cypher语句堆栈,这些堆栈作为Bag使用,并使用客户端运行此堆栈,例如
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $results = $client->runStack($stack);
标记您的Cypher语句
有时,您可能想要从堆栈中检索特定结果,一种简单的方法是标记您的Cypher语句。
标记通过run
或push
方法的第三个参数传递
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff'], 'user_create'); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[r:FOLLOWS]->(n2) RETURN id(r) as relId', ['uuid1' => '123-fff', 'uuid2' => '456-ddd'], 'user_follows'); $results = $client->runStack($stack); $followResult = $results->get('user_follows'); $followRelationshipId = $followResult->getRecord()->value('relId');
处理结果集
基础知识
run
方法返回一个单独的Result
对象。其他方法返回多个结果时,将返回一个可遍历的ResultCollection
对象。
Result
对象包含语句的records
和summary
,API中提供了以下方法
$result->firstRecord(); // Returns the first record of the Statement Result $result->records(); // Returns all records $result->summarize(); // Returns the ResultSummary
摘要
ResultSummary
包含Statement
、统计信息以及可用的查询计划
$summary = $result->summarize(); $query = $summary->statement()->text(); $stats = $summary->updateStatistics(); $nodesUpdated = $stats->nodesUpdated(); $propertiesSet = $stats->propertiesSet(); // Does the statement affected the graph ? $affected = $stats->containsUpdates();
记录值
每个记录包含Cypher查询返回的一行值
$query = 'MATCH (n:Person) n, n.name as name, n.age as age';
$result = $client->run($query);
foreach ($result->records() as $record) {
print_r($record->get('n')); // nodes returned are automatically hydrated to Node objects
echo $record->value('name') . PHP_EOL;
echo $record->value('age') . PHP_EOL;
}
客户端负责将图对象水化为PHP对象,因此对于节点、关系和路径都是如此
节点
labels()
:返回一个标签(字符串)数组identity()
:返回节点的内部IDvalues()
:返回节点的属性(数组)value($key)
:返回给定属性键的值hasValue($key)
:返回节点是否有具有给定键的属性keys()
:返回表示节点属性键的数组hasLabel($label)
:返回节点是否有给定的标签(布尔值)
关系
type()
:返回关系类型identity()
:返回关系的内部IDvalues()
:返回关系的属性(数组)value($key)
:返回给定属性键的值hasValue($key)
:返回关系是否有具有给定键的属性keys()
:返回表示关系属性键的数组startNodeIdentity
:返回起始节点IDendNodeIdentity
:返回结束节点ID
路径
start()
:返回路径的起始节点end()
:返回路径的结束节点length()
:返回路径的长度nodes()
:返回路径中的所有节点relationships
:返回路径中的所有关系
处理结果(从v3到v4)
围绕这个主题有3个主要概念
- a Result
- a Record
- a RecordValue
让我们看看浏览器中一个包含多种类型可能的查询
MATCH (n:Address)
RETURN n.address as addr, n, collect(id(n)) as ids
LIMIT 5
Result
Result
是一组 Record
对象的集合,你在浏览器中看到的每一行都是一个 Record
,它包含 Record Value
。
- 蓝色为 Result
- 橙色为 Record
- 绿色为 RecordValue
Record
与客户端的前几个版本相反,不再自动将所有记录合并成一个大的记录,因此你需要遍历 Result
中的所有记录
$query = 'MATCH (n:Address) RETURN n.address as addr, n, collect(id(n)) as ids LIMIT 5'; $result = $client->run($query); foreach ($result->records() as $record) { // here we do what we want with one record (one row in the browser result) print_r($record); }
Record Value
每个记录都包含一组 Record Value
,这些值由一个 key
标识,key 是你在 Cypher 查询的 RETURN
子句中给出的标识符。在我们的例子中,一个 Record
将包含以下键
- addr
- n
- ids
为了访问值,你将使用 Record
对象上的 get()
方法
$address = $record->get('addr');
值的类型取决于 Neo4j 返回的内容,在我们的例子中,将返回以下值
- 一个
string
类型的addr
值 - 一个
Node
类型的n
值 - 一个
integers
数组类型的ids
值
这意味着
$record->get('addr'); // returns a string $record->get('n'); // returns a Node object $record->get('ids'); // returns an array
Node
、Relationship
和 Path
对象有进一步的方法,因此如果你知道由标识符 n
返回的节点有一个 countries
属性,你可以这样访问它
$addressNode = $record->get('n'); $countries = $addressNode->value('countries');
Record
对象包含三个方法以提高 IDE 亲和力,即
$record->nodeValue('n'); $record->relationshipValue('r'); $record->pathValue('p');
这并没有提供额外的东西,只是 docblocks 提示 IDE 进行自动补全。
额外:ResultCollection
当你使用 Stack
对象一次发送多个语句时,它将返回一个包含多个 Result
的 ResultCollection
对象。因此,在访问记录之前,你需要遍历结果。
与事务一起工作
客户端提供了一个 Transaction 对象,它简化了与事务一起工作的方式。
创建事务
$tx = $client->transaction();
在这个阶段,还没有将任何内容发送到服务器(尚未发送 BEGIN 语句),这允许在提交之前堆叠查询或 Stack 对象。
堆叠查询
$tx->push('CREATE (n:Person) RETURN id(n)');
同样,到目前为止,什么也没有发送。
在事务中运行查询
有时你希望获取事务中语句的即时结果,这可以通过 run
方法完成
$result = $tx->run('CREATE (n:Person) SET n.name = {name} RETURN id(n)', ['name' => 'Michal']); echo $result->getRecord()->value("id(n)");
如果事务尚未开始,将自动执行事务的 BEGIN。
你也可以推送或运行 Stack
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $tx->pushStack($stack); // or $results = $tx->runStack($stack);
提交和回滚
如果你在你的事务中有排队语句(使用 push
方法添加的),并且你已经完成了工作,你可以提交事务并接收结果。
$stack = $client->stack(); $stack->push('CREATE (n:Person {uuid: {uuid} })', ['uuid' => '123-fff']); $stack->push('MATCH (n:Person {uuid: {uuid1} }), (n2:Person {uuid: {uuid2} }) MERGE (n)-[:FOLLOWS]->(n2)', ['uuid1' => '123-fff', 'uuid2' => '456-ddd']); $tx->pushStack($stack); $tx->pushQuery('MATCH (n) RETURN count(n)'); $results = $tx->commit();
提交后,你将无法在这个事务中 push
或 run
语句。
多连接操作
一般来说,你最好使用 HAProxy 在集群环境中运行 Neo4j。然而,有时你需要完全控制将语句发送到哪个实例。
让我们假设一个有 3 个 neo4j 节点的工作环境。
$client = ClientBuilder::create() ->addConnection('node1', 'bolt://10.0.0.1') ->addConnection('node2', 'bolt://10.0.0.2') ->addConnection('node3', 'bolt://10.0.0.3') ->setMaster('node1') ->build();
默认情况下,$client->run()
命令会将你的 Cypher 语句发送到列表中注册的第一个连接。
你可以通过指定别名作为 run 参数的第四个参数来指定将语句发送到哪个连接。
$result = $client->run('CREATE (n) RETURN n', null, null, 'node1');
客户端也了解手动配置的主连接,因此使用 Configuration
实例可以更轻松地发送写入操作。
$client->runWrite('CREATE (n:User {login: 123})');
辅助方法
$client->getLabels();
返回一个 Label
对象的数组。
事件分发
在 run
方法期间会分发 3 种类型的事件
PreRunEvent
: 在执行语句或堆栈之前。PostRunEvent
: 在执行语句或堆栈之后。FailureEvent
: 在发生故障时,你可以使用此事件禁用客户端抛出异常。
注册监听器
示例
$client = ClientBuilder::create() ->addConnection('default', 'bolt://') ->registerEventListener(Neo4jClientEvents::NEO4J_PRE_RUN, array($listener, 'onPreRun') ->build();
事件分发器可以通过客户端的 $client->getEventDispatcher
方法访问。
设置
超时(已弃用)
你可以为连接配置全局超时。
$client = ClientBuilder::create() ->addConnection('default', 'https://:7474') ->setDefaultTimeout(3) ->build();
默认超时时间为 5 秒。
此功能已弃用,将在版本 5 中删除。请参阅以下 HTTP 客户端设置。
TLS
通过在建立连接时传递一个 Configuration
实例,你可以启用 Bolt 协议的 TLS 加密,以下是一个简单的示例。
$config = \GraphAware\Bolt\Configuration::newInstance()
->withCredentials('bolttest', 'L7n7SfTSj')
->withTLSMode(\GraphAware\Bolt\Configuration::TLSMODE_REQUIRED);
$client = ClientBuilder::create()
->addConnection('default', 'bolt://hodccomjfkgdenl.dbs.gdb.com:24786', config)
->build();
HTTP 客户端设置
我们使用 HTTPlug 来提供对 HTTP 客户端的完全控制。Neo4jClient 的第 4 版默认使用 Guzzle6 以保持向后兼容。第 5 版将提供选择任何客户端的选项。有关 HTTPlug 的更多信息,请参阅他们的文档 。
要配置客户端,你可以将其添加到 Configuration
。下面是一个使用 php-http/curl-client
的示例。
use Http\Client\Curl\Client; $options = [ CURLOPT_CONNECTTIMEOUT => 3, // The number of seconds to wait while trying to connect. CURLOPT_SSL_VERIFYPEER => false // Stop cURL from verifying the peer's certificate ]; $httpClient = new Client(null, null, $options); $config = \GraphAware\Neo4j\Client\HttpDriver\Configuration::create($httpClient); $client = ClientBuilder::create() ->addConnection('default', 'http://neo4j:password@localhost:7474', $config) ->build();
许可证
该库根据 MIT 许可证发布,请参阅随此软件包提供的 LICENSE 文件。