在 Neo4j 中创建/匹配具有和不具有公共根节点的树结构



>我正在尝试重新创建一个树结构(在这种情况下是java包,但也可以是目录层次结构或其他任何东西(,与常见的起始节点匹配并在路径不同的地方发散。显然,同名的叶节点不是同一个节点。

例如:a.b.c.d将变成(a)-(b)-(c)-(d)a.b.c也会变成(a)-(b)-(c):相同的基础,因此是路径的一部分。

我尝试了以下方法:

unwind ['a.b.c.d', 'x.a.b.c'] as pkg 
with split(pkg, '.') as packages 
foreach (idx in range(0, size(packages) - 2) | 
  merge (pkg1:Package{name: packages[idx]}) 
  merge (pkg2:Package{name: packages[idx+1]}) 
  merge (pkg1)<-[:IN_PACKAGE]-(pkg2) 
) 

到目前为止,这运行良好,直到我添加一些结构(例如x.a.b然后它的a.b节点与a.b.c.da.b节点匹配。目前的结果是:(x)-(a)-(b)-(c)-(d)虽然它应该是两条不同的路径:(a)-(b)-(c)-(d)(x)-(a)-(b)。我看到了问题,那就是每个包都是单独匹配的,而不是从第一个节点开始的上下文中。

诸如 (a)-(b)-(c)-(e)(a)-(b)-(c)-(d) 之类的路径应导致

(a)-(b)-(c)-(d)
          -(e)

那么如何匹配常见的起始节点呢?

这里更好的方法是让每个 :P ackage 节点包含完整的包名称(除了其子包(。这允许包"a.b.c.d"与"x.b.c.d"区分开来。

不幸的是,Neo4j没有很好的文本操作支持来分解每个级别的完整包。为此,您需要APOC程序,并且需要跳过一些障碍才能到达此处。

此查询应该可以解决问题

UNWIND ['a.b.c.d', 'a.b.c.e','x.b.c.d'] as pkg 
WITH pkg, split(pkg, '.') as packages
UNWIND range(1,size(packages)) as index
WITH packages[index - 1] as subpackage, apoc.text.join(packages[..index], '.') as myPkg, apoc.text.join(packages[..index - 1], '.') as parentPackage
WITH subpackage, myPkg, parentPackage
MERGE (package:Package{name:myPkg, subpackage:subpackage})
WITH package, parentPackage
WHERE parentPackage <> ''
MERGE (parent:Package{name:parentPackage})
MERGE (parent)<-[:IN_PACKAGE]-(package)

最新更新