首页 > 解决方案 > 如何处理密码查询常见节

问题描述

我正在编写一堆查询以便在 Neo4j 中构建一棵树,但是为了添加不同类型的新数据,我正在为每个查询编写相同的开头节。

示例:我希望能够在Root(identifier=Root1)->A(identifier=1)->B(identifier=2)...不修改其他根指向的树的情况下添加。

我所有的查询都是从

Match
    (root:`Root` {identifier=$identifier})
Create 
    (root)-[:`someRel`]->(a:`A` {identifier=$a_identifier})

然后过了一段时间,A 需要一个孩子:

Match 
    (root:`Root` {identifier=$identifier})
    -[:`someRel`]->
    (a:`A` {identifier=$a_identifier})
Create 
    (a)-[:`someOtherRel`]->(b:`B` {identifier=$b_identifier})

然后又过了一​​段时间,也许 B 需要一个孩子,我必须使用相同的开头节来到达 A,然后再添加一个以得到正确的 B。

是否有一些我缺少的功能可以让我不必在每次我想要到达正确的 B(或 C 或 D)时建立那些开头的节,或者我只需要使用字符串连接来做到这一点?

字符串连接示例:(python)

MATCH
  {ROOT_LOOKUP_STANZA},
  {A_LOOKUP_STANZA},
  {B_LOOKUP_STANZA},
CREATE
  (b)-[:`c_relationship`]->(c:`C` {...})

一些附加说明:

Root(root)->A(a)->B(b) Root(root)->A(a1)->B(b)

在这种情况下,B(b) 引用了两个不同的节点,因为它们的父节点不同。

标签: neo4jcypher

解决方案


所以你的主要问题是孩子没有唯一的ID,只有根节点有唯一的ID。Neo4j 没有任何机制(还)将一个查询的最终上下文携带到另一个查询的开头,并且不保证节点内部 id 在查询之间是相同的。因此,对于您的数据,您必须匹配整个链以确保匹配要附加到的正确节点。不过,您可以做一些事情来使这变得不必要。

添加一个 UUID

通过向每个节点添加一个普遍唯一的 id(并对该属性进行索引),您将能够在该 id 上进行匹配,并保证没有冲突,并且在查询中它是相同的。任何时候使用节点内部 ID 都会很有用,这是您可以在数据中使用 UUID 的好兆头。(如果数据被镜像到其他数据库也有帮助)

将路径存储为唯一 ID

您可能不知道在 Neo4j 中分配的 UUID(因为它不在源数据中),但在树中您可以创建一个唯一的 ID,格式为<parent-ID>_<index><sorted-labels><source-id>. 这里的想法是保证父级有一个唯一的 id,并且您将该 id 与使该子级对该父级唯一的信息相结合。这允许您生成确定性的唯一 ID。(需要一个树数据结构,具有唯一的根 id)在大多数情况下,您可以不考虑索引部分(即源数据中的列表/数组的情况)。本质上,您将从根节点到该节点的路径存储为节点唯一 ID。(同样,您将需要此 id 的索引)

批处理作业

如果这只是一项工作的一部分,另一种选择是将您想要进行的更改集中起来,并生成一个密码来完成所有这些,而 Neo4j 已经获取了所有内容。


推荐阅读