我正在尝试重新创建一个树结构(在这种情况下是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
的{{1}}节点匹配。目前的结果是:a.b.c.d
,而它应该是两条不同的路径:(x)-(a)-(b)-(c)-(d)
和(a)-(b)-(c)-(d)
。我看到了问题,即每个包都是单独匹配的,而不是从第一个节点开始的上下文中。
(x)-(a)-(b)
和(a)-(b)-(c)-(e)
之类的路径应该会产生
(a)-(b)-(c)-(d)
那么如何匹配常见的起始节点?
答案 0 :(得分:0)
这里更好的方法是每个:Package节点包含完整的包名(除了它的子包)。这允许包&#39; a.b.c.d&#39;与&#39; x.b.c.d&#39;。
不同不幸的是,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)