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

时间:2018-04-11 15:50:53

标签: neo4j tree cypher

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

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

1 个答案:

答案 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)