【问题标题】:How to get tree structure that has access rights on each node如何获得对每个节点具有访问权限的树结构
【发布时间】:2022-01-06 13:32:59
【问题描述】:

我有一个像文件夹结构一样的树结构,所以对于一个没有深度限制的嵌套项目的项目,每个节点都有访问权限。

这是我的图表:

这是我的查询:

MATCH (a:Account {name: "bob"})-[r:VIEWER | EDITOR]->(c:Project)

MATCH (c)<-[:IS_PARENT*]-(p)
WHERE (p)<-[:VIEWER | EDITOR]-(a)

WITH TYPE(r) as relation, p, collect(distinct c) AS children

RETURN {name: p.name, Children: [c in children | {name: c.name, access:relation}]}

这是我的结果:

这就是我想要得到的:

我的问题是结果被分成两个结果,nested child 没有嵌套在cohort 中。

另一件棘手的事情是,如果我与它没有关系,我不想获得一个节点。

例如这里我删除了bobcohort之间的关系:

所以我不能在我的结果中得到cohort,像这样:

如果你想试试,这是我的数据:

MERGE (project:Project:RootProject {name: "project test"})
MERGE (child1:Project {name: "cohort"})
MERGE (child2:Project {name: "protocol"})
MERGE (child3:Project {name: "experience"})
MERGE (child4:Project {name: "nested child"})

MERGE (project)-[:IS_PARENT]->(child1)
MERGE (project)-[:IS_PARENT]->(child2)
MERGE (project)-[:IS_PARENT]->(child3)
MERGE (child1)-[:IS_PARENT]->(child4)

MERGE (bob:Account {name: "bob"})
 MERGE (bob)-[:EDITOR]->(child4)
 MERGE (bob)-[:EDITOR]->(child2)
 MERGE (bob)-[:VIEWER]->(child3)
MERGE (bob)-[:VIEWER]->(child1)
 MERGE (bob)-[:VIEWER]->(project)

我尝试了很多东西,但我从来没有得到好的结果。

【问题讨论】:

  • 好帖子。它具有预期的结果、示例查询和示例数据。

标签: neo4j cypher


【解决方案1】:

这是我的答案。主要是将 json 对象构建为父项目,然后将祖父母项目构建为根项目,而不是将两者混合(第 10 行)。请注意,我删除了获取 VIEWER 或 EDITOR 关系,因为删除它们也更快。

//Get the root project from bob
MATCH (a:Account {name: "bob"})-[r]->(root:RootProject)
WITH a, root, {name:root.name, access:type(r)} as rootProject
//Get only those projects without nested parent 
MATCH (a)-[r]->(p:Project) WHERE EXISTS((p)-[:IS_PARENT]-(root))
WITH a, rootProject, p, type(r) as relations
//Get those projects with another parent (or grand parent of root project)
OPTIONAL MATCH (p)-[:IS_PARENT]->(gp:Project)<-[r]-(a)
//Collect the children and grandchildren
WITH rootProject, collect({children: {name: p.name, access:relations}, grandchild:(case when gp is null then [] else [{name:gp.name, access:type(r)}] end)}) as allChildren
RETURN {name: rootProject.name, access: rootProject.access, children: [c in allChildren]} as projects

【讨论】:

  • 您好,感谢您的回答,它有很大帮助,我有一个问题,如果我添加新的深度,它将无法正常工作。如果我在“嵌套子项”下添加“新子项”并具有 EDITOR 关系,它将不会显示在回复中 (cohort) -&gt; (nested child) -&gt; (new child) 我们如何编辑您的查询以从任何深度获取子项?
  • 您将添加另一个类似于第 8 行的可选匹配并将其添加到第 10 行的收集中。Neo4j 以固定的 json 格式返回响应,因此如果您希望它灵活,您可能需要使用 java 或 python 之类的另一层进行格式化。 Java 或 python 将调用你的 neo4j 查询并按照你想要的方式格式化数据。
  • 如果您对我的回答感到满意,请投票/接受。谢谢。
  • 好的,所以这对于像 100 个嵌套子级这样的未确定深度是不可扩展的?
【解决方案2】:

它可能不符合您的期望,但是这在可扩展性方面怎么样?

MATCH (a:Account {name: "bob"})-[r:VIEWER|EDITOR]->(c:Project)

MATCH path=(p)-[:IS_PARENT*]->(c)
WHERE (p)<-[:VIEWER | EDITOR]-(a)

WITH COLLECT(path) AS paths
CALL apoc.convert.toTree(paths, false, {
  nodes: {Project: ['name']},
  rels:  {IS_PARENT: ['name']}
}) YIELD value
RETURN value

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2022-06-15
    相关资源
    最近更新 更多