【问题标题】:Neo4j - How to create a nested object with a tree structureNeo4j - 如何创建具有树结构的嵌套对象
【发布时间】:2022-01-04 14:43:53
【问题描述】:

我有一个树结构,对我的树的每个节点都有访问权限,我想只在嵌套对象中获取我有权访问的节点,如下所示:

{
  name: "project 1",
  Children: [
   {name: "nested child"}
  ]
}

这是我的图形结构:

我想获取与Marion:VIEWER 关系的所有节点,这是我尝试过的查询,但我没有嵌套结构

MATCH path =(a:Account {firstName: "Marion"})-[:VIEWER]->()
WITH collect(path) AS paths
CALL apoc.convert.toTree(paths)
YIELD value
RETURN value;

我得到了这个结构

{
  "firstName": "Marion",
  "viewer": [
    {
      "_type": "Project",
      "name": "project 1",
      "_id": 1,
      "type": "project"
    },
    {
      "_type": "Child",
      "name": "nested child",
      "_id": 4,
      "type": "child"
    }
  ],
  "_type": "Account",
  "_id": 29,
}

nested child 应该在 project1 中的 children 对象中

父子关系的深度没有限制

有谁知道这是否可行?

如果您对我的图形结构有更好的想法,我愿意进行优化

编辑

感谢您的回答,它有效,但我想添加一些参数

除了:VIEWER,还可以有其他类型的关系 :VIEWER :EDITOR :OWNER

我需要知道Marion 与每个节点的关系

我已经进行了这个查询,但我不明白为什么我的结果被分成表格?

MATCH (c)<-[:IS_PARENT_OF*]-(p)
WHERE (p)<-[:VIEWER | EDITOR]-(a)
// collect the child nodes per project
WITH TYPE(r) as relation, p,collect(distinct c) AS children
// return a map that contains project and children names
RETURN {name: p.name, Children: [c in children | {name: c.name, access:relation}]}

结果

{
  "name": "project 1",
  "Children": [
    {
      "access": "EDITOR",
      "name": "Experimental design"
    }
  ]
}

{
  "name": "project 1",
  "Children": [
    {
      "access": "VIEWER",
      "name": "nested child"
    }
  ]
}

预期

{
  "name": "project 1",
  "Children": [
 {
      "access": "EDITOR",
      "name": "Experimental design"
    },
    {
      "access": "VIEWER",
      "name": "nested child"
    }
  ]
}

【问题讨论】:

    标签: neo4j


    【解决方案1】:

    根据您的节点可视化,我将假设项目节点与子节点具有不同的标签。

    我会尝试以下方法:

    // get the top-level project
    MATCH (a:Account {firstName: "Marion"})-[:VIEWER]->(p:Project)
    // get the child nodes
    MATCH (p)-[:IS_PARENT_OF*]->(child)
    WHERE (child)<-[:VIEWER]-(a)
    // collect the child nodes per project
    WITH p, collect(distinct child) AS children
    // return a map that contains project and children names
    RETURN {name: p.name, Children: [c in children | {name: c.name}]}
    

    编辑:

    添加了哈坎的答案

    // get the children
    MATCH (a:Account {firstName: "Marion"})-[:VIEWER]->(child:Child) 
    // get the parent project that is also viewable 
    MATCH (p)-[:IS_PARENT_OF*]->(child) 
    WHERE (p)<-[:VIEWER]-(a) 
    // collect the child nodes per project 
    WITH p, collect(distinct child) AS children 
    // return a map that contains project and children names 
    RETURN {name: p.name, Children: [c in children | {name: c.name}]}
    

    【讨论】:

    • 另外,反方向查询,最有可能性能更高,先匹配child,再查看child属于哪个项目。由于从子项目到项目只有一条路径,而从项目到子项目有许多路径,但只有一条是“正确路径”。
    • @Tomaž Bratanič 在第一个MATCH 中我们得到Project 节点,但Child 节点可能是结构的根,我如何更改查询以检查Project and Child第二个问题,我如何添加Marion 与返回对象中每个节点的关系类型,如下所示:` {name: c.name, access: }`
    • @Håkan Löfqvist 谢谢你的评论,这是个好主意,我明白你的意思,但你会怎么做呢?
    • 在第一个 MATCH 中,仅匹配 Marion 是 child 的查看者。然后换入 where 子句以检查 Marion 是否也是项目的查看者。
    • // 获取子项目 MATCH (a:Account {firstName: "Marion"})-[:VIEWER]->(child:Child) // 获取也可见的父项目 MATCH ( p)-[:IS_PARENT_OF*]->(child) WHERE (p)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-07-24
    • 2016-12-08
    相关资源
    最近更新 更多