php-graph-group / cypher-query-builder
Cypher 查询语言的具有观点的查询构建器
Requires
- laudis/neo4j-php-client: ^3.0.3
- wikibase-solutions/php-cypher-dsl: ^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.16
- kubawerlos/php-cs-fixer-custom-fixers: ^3.14
- phpunit/phpunit: ^10.1
- vimeo/psalm: ^5.11
This package is auto-updated.
Last update: 2024-09-04 21:23:50 UTC
README
通过具有观点的构建器模式,以流畅且易于理解的方式创建 Cypher 查询。
示例
简单模式匹配示例
此查询查找 Alice 和 Bob 的所有同事
use PhpGraphGroup\CypherQueryBuilder\QueryBuilder; $results = QueryBuilder::fromNode('a:Person') ->matchingRelationship('a', 'IS_COLLEAGUE', 'b:Person') ->whereIn('a.name', ['Alice', 'Bob']) ->return('b.name AS name') // Notice of the present tense implies the query gets executed immediately.
构建器运行此查询并返回结果
MATCH (a:Person)-[:IS_COLLEAGUE]->(b:Person) WHERE a.name IN $names RETURN b.name AS name
复杂模式匹配示例
此查询包含一个更复杂的模式,该模式正在使用模式构建器构建。
use PhpGraphGroup\CypherQueryBuilder\QueryBuilder; use PhpGraphGroup\CypherQueryBuilder\Builders\GraphPatternBuilder; GraphPatternBuilder::from('node:MyNode') // MATCH (node:MyNode) GraphPatternBuilder::from('MyNode', 'otherNode') // MATCH (otherNode:MyNode) GraphPatternBuilder::from('myNode:MyNode', 'otherNode') // MATCH (otherNode:MyNode) (TODO: log warning here?) GraphPatternBuilder::from('Hello') // MATCH (hello:Hello) GraphPatternBuilder::from('<Hello') // MATCH () <-[hello:Hello]-() GraphPatternBuilder::from('<Hello')->addChildNode('Heya') // MATCH () <- [hello:Hello] - (heya:Heya) // TODO: maybe rename this to addNode to allow for a parallel node, aka joining. // TODO: If a node gets joined by a child node, it should have an anonymous relationship. GraphPatternBuilder::from('MyNode')->addChildNode('MyOtherNode') // MATCH (myNode:MyNode), (myOtherNode:MyOtherNode) GraphPatternBuilder::from('MyNode')->addRelationship()->addChildNode('MyOtherNode') // MATCH (myNode:MyNode)--(myOtherNode:MyOtherNode) GraphPatternBuilder::from(name: 'noLabel') // MATCH (noLabel) // TODO: Should it inject numbering in the automatic naming? -> no // TODO: Should we pre-emptively throw an error or let the syntax error be found by the database? // => first version should stay away from this, but we can revisit. GraphPatternBuilder::from('MyNode')->addRelationship()->addChildNode('MyNode') // MATCH (myNode:MyNode) - [] -> (myNode:MyNode) $results = QueryBuilder::from(GraphPatternBuilder::from('node:MyNode') ->addRelationship('<Parent') ->addChildNode('sibling1:MyNode')->end() ->addChildNode('sibling2:MyNode')->end() ->end() ->addRelationship('Parent>') ->addChildNode('grandParent:MyNode')->end() ->end() )->whereIn('sibling1.name', ['Harry', 'Bart']) ->andWhere('sibling2.name', '<>', 'Maria') ->andWhere('grandParent.age', '>=', 70) ->count('grandParent')
变为
MATCH (node:MyNode), (sibling1:MyNode)
简单创建示例
创建一个新的 Person 并使其成为 Alice 的同事。
use PhpGraphGroup\CypherQueryBuilder\QueryBuilder; $results = QueryBuilder::new() ->matchingNode('a:Person') ->where('a.name', '=', 'Alice') ->creatingNode('b:Person') ->creatingRelationship('a', 'IS_COLLEAGUE', 'b') ->create(['b.name' => 'Bob'])
构建器运行此查询
MATCH (a:Person) WHERE a.name = $param0 CREATE (b:Person), (a)-[:IS_COLLEAGUE]->(b) SET b.name = $param1
简单更新示例
工作原理
Cypher 是一种功能强大的查询语言,提供了极大的灵活性。然而,这种灵活性可能会使得查询的理解和维护变得困难,尤其是在查询构建器的形式下。
此库旨在通过提供易于理解的流畅构建器模式,使编写和维护 Cypher 查询变得更加容易。
它具体限制了可能性,以便构建器更容易推理和使用。所有数据库操作仍然是可能的,但不再可能连续使用长而复杂的子句。
这是因为此查询构建器的主要观点和观点是,长而复杂的多个子句查询是不受欢迎的。它们难以理解,且查询的性能很可能下降。
构建器只提供每种子句的一个,并且这些子句的位置是固定的
MATCH { match patterns }
OPTIONAL MATCH* { optional match patterns }
CALL* { subquery }
WHERE { where conditions }
DELETE { deleted variables }
DETACH DELETE { deleted variables }
REMOVE { removed properties & labels }
CREATE { create patterns }
SET { set assignments }
MERGE { merge pattern }
ON CREATE SET { set assignments }
ON MATCH SET { set assignments }
RETURN { return expressions }
ORDER BY { ASC|DESC } { order expressions }
SKIP { skip count }
LIMIT { limit count }
查询构建器将只运行查询的某些部分,具体取决于您调用的方法。这些方法是直观且易于理解的
在某些情况下,会使用 UNWIND 在幕后实现以允许大量插入,但这超出了本介绍的范畴。
变量使用
变量用于引用节点、关系和别名。别名可以引用属性、节点、关系或函数调用结果。
由于构建器构建查询的方式,Cypher 不允许变量重新赋值。为了保持灵活性并允许使用原始语句,构建器不会检查变量的存在或重新赋值。只有当查询构建并发送到服务器后,才会发生错误。
属性使用
属性指代变量上的属性。这意味着用户应该使用点符号来明确地引用属性。如果不使用点符号而只引用属性,构建器将使用它来引用构建器入口节点或关系的变量上的属性。
use PhpGraphGroup\CypherQueryBuilder\QueryBuilder; // Refer unambiguously to the property 'name' on the variable 'p' $name = QueryBuilder::from('Person', 'p') ->where('p.name', '=', 'Alice') ->returning('p.name') ->only() // Runs like: // MATCH (p:Person) WHERE p.name = $param0 RETURN p.name AS name LIMIT 1 // Refer to the property of p without using the dot notation. $lastNames = QueryBuilder::from('Person', 'p') ->where('name', '=', 'Alice') ->pluck('lastName') // Runs like: // MATCH (p:Person) WHERE p.name = $param0 RETURN p.lastName AS lastName // Automatically generate a name based on the Label and get al the friends of Alice for over a year. $friends = QueryBuilder::from('Person') ->matchingRelationship('person', 'FRIENDS_WITH', 'friend', 'friendsWith') ->matchingNode('Person', 'friend') ->where('friendsWith.since', '<=', (new DateTime())->sub(new DateInterval('P1Y'))) ->andWhere('person.name', '=', 'Alice') ->return('friend.name AS name', 'friendsWith.since AS friendsSince') // Runs like: // MATCH (person:Person)-[friendsWith:FRIENDS_WITH]->(friend:Person) WHERE friendsWith <= $param0 AND person.name = $param1 RETURN friend.name AS name, friendsWith.since AS friendsSince