如何将此 Neo4j 密码查询转换为 PHP 密码 DSL?

问题描述 投票:0回答:1

我们正在使用 php-cypher-dsl 库将 Neo4j cypher 查询转换为 PHP cypher DSL(域特定语言),以获得更大的灵活性。

我们为此苦苦挣扎,因为该库的文档并没有真正详细地解释如何使用它。假设我们在 cypher Neo4j 中有一个简单的查询:

MATCH (a:Resource), (b:Resource) 
WHERE a.uri = $uri AND b.uri = $object
CREATE (a)-[r:{$propertyUri}]->(b)
RETURN type(r)

我们如何将这个 Neo4j cypher 查询转换为 PHP cypher DSL?

php neo4j cypher neo4jphp
1个回答
0
投票

您需要做的第一件事是创建您想要匹配的所有节点,以及您想要使用的参数,如下所示:

$a = node("Resource"); // (a:Resource)
$b = node("Resource"); // (b:Resource)

$uri = parameter("uri"); // $uri
$object = parameter("object"); // $object

node
函数将节点的标签作为其唯一参数,而
parameter
函数将参数名称作为其唯一参数。接下来,您可以开始编写查询。您可以使用
query
函数启动新查询,如下所示:

$query = query();

这会返回一个

Query
对象,该对象有许多方法可以向查询添加新子句,例如
match
set
where
create
。这些对应于 Cypher 提供的条款。

我们首先匹配节点

$a
$b
:

$query = query() // Start a new query
    ->match([$a, $b]) // Match on both "a" and "b"
    ...

接下来,我们要创建匹配条件。 php-cypher-dsl 附带了用于创建此类表达式的构建器模式:

    ...
    ->where($a->property("uri")->equals($uri)->and($b->property("uri")->equals($object))
    ...

接下来,在创建

CREATE
子句之前,我们需要创建一个新变量
$r
,该变量在
CREATE
RETURN
子句之间共享:

$r = variable(); // Create a new variable

要创建

CREATE
子句,我们需要执行一些技巧来再次从节点中删除
:Resource
标签。这部分API还需要一些改进。我们可以使用
node()->withVariable($a->getVariable())
获得具有相同变量的新节点。总而言之,看起来像:

    ...
    ->create(node()->withVariable($a->getVariable())->relationshipTo(node()->withVariable($b->getVariable()), type: $propertyUri, name: $r))
    ...

最后我们就可以返回我们想要的值了:

    ...
    ->returning(Procedure::raw('type', $r)) // The "type" function is not implemented natively, so we use raw
    ->toQuery(); // Convert the query to a string

所有放在一起,代码如下所示:

use WikibaseSolutions\CypherDSL\Expressions\Procedures\Procedure;
use function WikibaseSolutions\CypherDSL\node;
use function WikibaseSolutions\CypherDSL\parameter;
use function WikibaseSolutions\CypherDSL\query;
use function WikibaseSolutions\CypherDSL\variable;

$propertyUri = "http://example.com";

$a = node("Resource");
$b = node("Resource");
$uri = parameter("uri");
$object = parameter("object");
$r = variable();

$query = query()
    ->match([$a, $b])
    ->where($a->property("uri")->equals($uri)->and($b->property("uri")->equals($object)))
    ->create(node()->withVariable($a->getVariable())->relationshipTo(node()->withVariable($b->getVariable()), type: $propertyUri, name: $r))
    ->returning(Procedure::raw('type', $r))
    ->toQuery();

我认为这比使用带变量的普通查询可读性要差得多。如果您不需要复杂的逻辑来构建查询(并且仅使用预先创建的查询,例如您问题中的查询),我建议您不要使用此库。

© www.soinside.com 2019 - 2024. All rights reserved.