查询创建

本章讨论在使用SDN抽象层时查询的技术创建。会进行一些简化,因为我们不会讨论所有可能的情况,而是坚持其背后的一般思想。

保存

除了find/load操作,save操作是处理数据时最常用的操作之一。保存操作调用通常会向数据库发出多个语句,以确保生成的图模型与给定的Java模型匹配。

  1. 将创建联合语句,该语句要么在找不到节点的标识符时创建节点,要么在节点存在时更新节点的属性。

    (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))

  2. 如果实体**不是**新的,则域模型中第一个找到类型的所有关系将从数据库中删除。

    (MATCH (startNode)-[rel:Has]→(:Hobby) WHERE id(startNode) = $fromId DELETE rel)

  3. 相关实体将以与根实体相同的方式创建。

    (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))

  4. 关系本身将被创建

    (MATCH (startNode) WHERE id(startNode) = $fromId MATCH (endNode) WHERE id(endNode) = 631 MERGE (startNode)-[:Has]→(endNode))

  5. 如果相关实体也与其他实体有关系,则将开始与2.相同的过程。

  6. 对于根实体上的下一个定义关系,从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会回退到级联/数据驱动的查询创建。从一个查找特定节点并考虑条件的初始查询开始,它遍历结果节点,如果它们的关系也已映射,则会即时创建进一步的查询。这个查询创建和执行循环将继续,直到没有查询找到新的关系或节点。创建方式可以类比保存/更新过程。

© . This site is unofficial and not affiliated with VMware.