此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data Neo4j 7.5.2! |
查询创建
本章介绍使用 SDN 抽象层时查询的技术创建。 会有一些简化,因为我们不会讨论所有可能的情况,而是坚持其背后的总体思路。
救
除了find/load
作save
作是处理数据时最常用的方法之一。
保存作调用通常会针对数据库发出多个语句,以确保生成的图形模型与给定的 Java 模型匹配。
-
将创建一个联合语句,如果找不到节点的标识符,则创建节点,如果节点本身存在,则更新节点的属性。
(
OPTIONAL MATCH (hlp:Person) WHERE id(hlp) = $__id__ WITH hlp WHERE hlp IS NULL CREATE (n:Person) SET n = $__properties__ RETURN id(n) UNION MATCH (n) WHERE id(n) = $__id__ SET n = $__properties__ RETURN id(n)
) -
如果实体不是新的,则域模型中第一个找到的类型的所有关系都将从数据库中删除。
(
MATCH (startNode)-[rel:Has]→(:Hobby) WHERE id(startNode) = $fromId DELETE rel
) -
相关实体的创建方式与根实体相同。
(
OPTIONAL MATCH (hlp:Hobby) WHERE id(hlp) = $__id__ WITH hlp WHERE hlp IS NULL CREATE (n:Hobby) SET n = $__properties__ RETURN id(n) UNION MATCH (n) WHERE id(n) = $__id__ SET n = $__properties__ RETURN id(n)
) -
关系本身将被创建
(
MATCH (startNode) WHERE id(startNode) = $fromId MATCH (endNode) WHERE id(endNode) = 631 MERGE (startNode)-[:Has]→(endNode)
) -
如果相关实体也与其他实体有关系,则与 2 中的过程相同。将开始。
-
对于根实体上的下一个定义关系,从 2 开始。但将 first 替换为 next。
如您所见,SDN 尽最大努力使您的图形模型与 Java 世界保持同步。 这就是为什么我们真正建议您不要加载、作和保存子图的原因之一,因为这可能会导致关系从数据库中删除。 |
多个实体
这save
作重载了接受相同类型的多个实体的功能。
如果您正在使用生成的 id 值或使用乐观锁定,则每个实体都将产生单独的CREATE
叫。
在其他情况下,SDN 将创建一个包含实体信息的参数列表,并为其提供MERGE
叫。
UNWIND $__entities__ AS entity MERGE (n:Person {customId: entity.$__id__}) SET n = entity.__properties__ RETURN collect(n.customId) AS $__ids__
参数如下所示
:params {__entities__: [{__id__: 'aa', __properties__: {name: "PersonName", theId: "aa"}}, {__id__ 'bb', __properties__: {name: "AnotherPersonName", theId: "bb"}}]}
负荷
这load
文档不仅会向您展示查询的 MATCH 部分的外观,还会显示数据是如何返回的。
最简单的加载作是findById
叫。
它将匹配所有节点与您查询的类型的标签,并对 id 值进行过滤。
MATCH (n:Person) WHERE id(n) = 1364
如果提供了自定义 ID,则 SDN 将使用您定义的属性作为 ID。
MATCH (n:Person) WHERE n.customId = 'anId'
要返回的数据被定义为地图投影。
RETURN n{.first_name, .personNumber, __internalNeo4jId__: id(n), __nodeLabels__: labels(n)}
如您所见,其中有两个特殊字段:__internalNeo4jId__
和__nodeLabels__
.
在将数据映射到 Java 对象时,两者都至关重要。
的值__internalNeo4jId__
是id(n)
或提供的自定义 ID,但在映射过程中必须存在一个要引用的已知字段。
这__nodeLabels__
确保可以找到并映射此节点上所有已定义的标签。
当使用继承并且您不查询具体类或定义了仅定义超类型的关系时,这是必需的。
谈论关系:如果您在实体中定义了关系,它们将作为模式推导式添加到返回的映射中。上面的返回部分将如下所示:
RETURN n{.first_name, …, Person_Has_Hobby: [(n)-[:Has]→(n_hobbies:Hobby)|n_hobbies{__internalNeo4jId__: id(n_hobbies), .name, __nodeLabels__: labels(n_hobbies)}]}
SDN 使用的地图投影和模式推导可确保仅查询您定义的属性和关系。
如果您具有自引用节点或创建的模式可能会导致返回的数据循环,SDN 回退到级联/数据驱动的查询创建。从查找特定节点的初始查询开始,并考虑条件,它会逐步执行生成的节点,如果它们的关系也已映射,则会动态创建进一步的查询。此查询创建和执行循环将继续进行,直到没有查询找到新的关系或节点。创建方式可以与保存/更新过程类似。