>我正在尝试重新创建一个树结构(在这种情况下是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.d
的a.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)