首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Neo4层次遍历

Neo4层次遍历
EN

Stack Overflow用户
提问于 2015-05-12 14:05:23
回答 1查看 98关注 0票数 3

我在neo4j中存储了一些分层数据,需要查询才能为特定用户查找父节点的所有子节点。基本情况是:

代码语言:javascript
复制
(Root Task {control: 1})
    (Child Task 2 {control: 2})
    (Child Task 3 {control: 3})
        (Child Task 4 {control: 4})

子任务与父任务有:CHILD_OF关系。所以这一切都很好,我可以让父母的孩子。使用下面的查询,我将返回子任务4。

代码语言:javascript
复制
MATCH (rootTask:Task {control: 3}), (user:User {control: 60})
,(childTask:Task)-[:CHILD_OF*]->(rootTask)
WHERE (user)-[:LINKED_TO]->(childTask)
RETURN childTask

问题在于用户需要重新安排结构,但这仅仅是为了自己。因此,我引入了一种新的关系,它包含了对用户的引用。添加了CHILD_OF_<usercontrol>,如果它存在,它应该优先于CHILD_OF关系。

因此,如果用户60决定(子任务4)任务属于(根任务)而不是(子任务3),则创建两个链接:

代码语言:javascript
复制
MERGE (Level 4 task)-[:CHILD_OF]->(Child Task 3)
MERGE (Level 4 task)-[:CHILD_OF_60]->(Root Task)

他现在的看法基本上是:

代码语言:javascript
复制
(Root Task {control: 1})
    (Child Task 2 {control: 2})
    (Child Task 3 {control: 3})
    (Child Task 4 {control: 4})

因此,现在当我要求(子任务3)的子任务,对于用户60,我不希望(子任务4)返回。

使用前面的查询并添加特定于用户的关系和附加约束,如果子任务具有指向未绑定任务的用户特定链接,则不返回子任务。期望它将返回(子任务4)的子任务,因为它们只有链接到的CHILD_OF关系。排除具有用户特定链接的子任务的逻辑也有缺陷,因为它可能实际上指向同一个父节点。

代码语言:javascript
复制
MATCH (rootTask:Task {control: 3}), (user:User {control: 60})
,(childTask:Task)-[:CHILD_OF|CHILD_OF_60*]->(rootTask)
WHERE (user)-[:LINKED_TO]->(childTask) 
AND NOT (childTask)-[:CHILD_OF_60]-(:Task)
RETURN childTask

我所需要的逻辑的本质是,如果任务存在关系CHILD_OF_60,那么遵循该关系,忽略默认的CHILD_OF关系。

试验数据

代码语言:javascript
复制
MERGE (ruan :User {control: 50, fullname: 'Ruan'})
MERGE (amber :User {control: 60, fullname: 'Amber'})
MERGE (task1 :Task {control: 1, subject: 'Root Task:'})
MERGE (task2 :Task {control: 2, subject: 'Child of Root:'})
MERGE (task3 :Task {control: 3, subject: 'User properties'})
MERGE (task4 :Task {control: 4, subject: 'User parent links'})
MERGE (task5 :Task {control: 5, subject: 'Hierarchy Traversal'})
MERGE (task6 :Task {control: 6, subject: 'Parent'})
MERGE (task7 :Task {control: 7, subject: 'Child'})
MERGE (task8 :Task {control: 8, subject: 'Query1'})
MERGE (task2)-[:CHILD_OF]->(task1)
MERGE (task3)-[:CHILD_OF]->(task2)
MERGE (task4)-[:CHILD_OF]->(task2)
MERGE (task5)-[:CHILD_OF]->(task2)
MERGE (task6)-[:CHILD_OF]->(task5)
MERGE (task7)-[:CHILD_OF]->(task5)
MERGE (task8)-[:CHILD_OF]->(task7)
MERGE (ruan)-[:LINKED_TO]->(task1)
MERGE (ruan)-[:LINKED_TO]->(task2)
MERGE (ruan)-[:LINKED_TO]->(task3)
MERGE (ruan)-[:LINKED_TO]->(task4)
MERGE (ruan)-[:LINKED_TO]->(task5)
MERGE (ruan)-[:LINKED_TO]->(task6)
MERGE (ruan)-[:LINKED_TO]->(task7)
MERGE (ruan)-[:LINKED_TO]->(task8)
MERGE (amber)-[:LINKED_TO]->(task1)
MERGE (amber)-[:LINKED_TO]->(task2)
MERGE (amber)-[:LINKED_TO]->(task3)
MERGE (amber)-[:LINKED_TO]->(task4)
MERGE (amber)-[:LINKED_TO]->(task5)
MERGE (amber)-[:LINKED_TO]->(task6)
MERGE (amber)-[:LINKED_TO]->(task7)
MERGE (amber)-[:LINKED_TO]->(task8)
MERGE (task2)-[:CHILD_OF]->(task1)
MERGE (task3)-[:CHILD_OF]->(task2)
MERGE (task4)-[:CHILD_OF]->(task2)
MERGE (task5)-[:CHILD_OF]->(task2)
MERGE (task6)-[:CHILD_OF]->(task5)
MERGE (task7)-[:CHILD_OF]->(task5)
MERGE (task8)-[:CHILD_OF]->(task7)
MERGE (task5)-[:CHILD_OF_60]->(task1)
MERGE (task3)-[:CHILD_OF_60]->(task1)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-12 16:51:50

这是一个有趣的工作。我在这里制作了一个GraphGist来演示我的建议:

http://graphgist.neo4j.com/#!/gists/54d8b5ef8cfb85197aa4

但我也会把解决办法放在这里:

代码语言:javascript
复制
MATCH
  (rootTask:Task { control: 1 }),
  path=(childTask:Task)-[:CHILD_OF|CHILD_OF_60*1..]->rootTask,
  (user:User { control: 60 })-[:LINKED_TO]->childTask
WITH childTask, path AS the_path, path
UNWIND nodes(path) AS node
OPTIONAL MATCH node-[:CHILD_OF_60]->(otherParent:Task)
WITH childTask, the_path, collect(otherParent IS NULL OR otherParent IN nodes(the_path))[0..-1] AS otherParentResults
WHERE ALL(result IN otherParentResults WHERE result)
RETURN DISTINCT childTask

基本上,我正在获取路径,通过CHILD_OF_60关系检查叶节点是否有另一个父节点,然后返回子节点,如果它没有另一个父节点,或者otherParent不在祖先路径中。

如果这个解决方案是由自动化测试支持的,我会对它感到更舒服的,但是尝试一下吧!)

此外,作为一项规则,我尽量不设置变量关系名。您可能想考虑在您的user_id关系中有一个可选的CHILD_OF属性。或者,您可能有类似于CHILD_OF_FOR_USER关系类型的东西,它具有user_id属性。

编辑:我编辑了上面的查询和GraphGist,以处理根节点路径中具有移动祖先的子节点

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30193310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档