【问题标题】:Using Cypher to return nested, hierarchical JSON from a tree使用 Cypher 从树中返回嵌套的分层 JSON
【发布时间】:2016-03-18 00:08:30
【问题描述】:

我目前正在使用 console.neo4j.org 上的示例数据来编写输出分层 JSON 的查询。

示例数据是用

创建的
create (Neo:Crew {name:'Neo'}), (Morpheus:Crew {name: 'Morpheus'}), (Trinity:Crew {name: 'Trinity'}), (Cypher:Crew:Matrix {name: 'Cypher'}), (Smith:Matrix {name: 'Agent Smith'}), (Architect:Matrix {name:'The Architect'}),
(Neo)-[:KNOWS]->(Morpheus), (Neo)-[:LOVES]->(Trinity), (Morpheus)-[:KNOWS]->(Trinity),
(Morpheus)-[:KNOWS]->(Cypher), (Cypher)-[:KNOWS]->(Smith), (Smith)-[:CODED_BY]->(Architect)

理想的输出如下

name:"Neo"
children: [
  { 
    name: "Morpheus",
    children: [
      {name: "Trinity", children: []}
      {name: "Cypher", children: [
        {name: "Agent Smith", children: []}
      ]}
    ]
  }
]
}

现在,我正在使用以下查询

MATCH p =(:Crew { name: "Neo" })-[q:KNOWS*0..]-m
RETURN extract(n IN nodes(p)| n)

得到这个

[(0:Crew {name:"Neo"})]
[(0:Crew {name:"Neo"}), (1:Crew {name:"Morpheus"})]
[(0:Crew {name:"Neo"}), (1:Crew {name:"Morpheus"}), (2:Crew {name:"Trinity"})]
[(0:Crew {name:"Neo"}), (1:Crew {name:"Morpheus"}), (3:Crew:Matrix {name:"Cypher"})]
[(0:Crew {name:"Neo"}), (1:Crew {name:"Morpheus"}), (3:Crew:Matrix {name:"Cypher"}), (4:Matrix {name:"Agent Smith"})]

有什么技巧可以解决这个问题吗?谢谢

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    在neo4j 3.x 中,在neo4j 服务器上安装APOC plugin 后,可以调用apoc.convert.toTree 过程来生成类似的结果。

    例如:

    MATCH p=(n:Crew {name:'Neo'})-[:KNOWS*]->(m)
    WITH COLLECT(p) AS ps
    CALL apoc.convert.toTree(ps) yield value
    RETURN value;
    

    ... 将返回如下所示的结果行:

        {
          "_id": 127,
          "_type": "Crew",
          "name": "Neo",
          "knows": [
            {
              "_id": 128,
              "_type": "Crew",
              "name": "Morpheus",
              "knows": [
                {
                  "_id": 129,
                  "_type": "Crew",
                  "name": "Trinity"
                },
                {
                  "_id": 130,
                  "_type": "Crew:Matrix",
                  "name": "Cypher",
                  "knows": [
                    {
                      "_id": 131,
                      "_type": "Matrix",
                      "name": "Agent Smith"
                    }
                  ]
                }
              ]
            }
          ]
        }
    

    【讨论】:

    • The APOC repo 给出了名字的历史。
    • 是的。我指的是这个问题中的样本也来自矩阵。
    • 这是迄今为止 APOC 插件最强大的功能(至少对我来说很好),并且很容易通过 Neo4j 映像引入 Docker(请参阅文档),如果使用 docker-compose,请使用卷:- :/plugins,“build”,然后“up”。感谢分享这个@cybersam,改变了我的生活和空闲时间!
    【解决方案2】:

    这是一个关于这个重要主题的非常有用的线程,我想在深入研究后添加一些想法。

    首先,使用 APOC “toTree” proc 有一些限制,或者说,依赖关系。你的架构有多“树状”真的很重要。例如,上面的 APOC 调用中缺少 LOVES 关系,我理解为什么——在使用“toTree”时很难包含这种关系——简单的添加有点像在层次结构中添加属性,而是作为一种关系。不错,但会混淆简单的 KNOWS 树。重点是,一个很好的问题是“我如何应对这些挑战”。这个回复就是关于这个的。

    我确实建议您提高 JSON 技能,因为这将为您提供更精细的控制。就个人而言,我发现我最初的探索有些痛苦。可能是因为我是一个 XML 人 :) 但是一旦你弄清楚所有 [、{ 和 ('s是可以很容易地成为一个类的东西,它允许一种很好的方式将其推回您的应用程序。

    我发现 perf 对于“toTree”与仅要求 JSON 相比也是一个挑战。我在下面添加了一个非常简单的外观,以了解您的 RETURN 可能是什么样子。它遵循以下 BN 格式。我希望看到这个更成熟的创建,因为可能性是多种多样的,但这是我发现有用的东西,因此我现在将发布这个不成熟的版本。像他们说的那样; “更深入的潜水留给读者”?

    我混淆了这些值,但这是一个实际查询,我将其称为图架构的一个非常糟糕的示例,其许多设计“错误”在尝试访问整体报告时会导致一些严重的性能问题图表。在这个例子中,我继承的初始报告查询在服务器上花费了很多分钟,并且无法在我的笔记本电脑上运行 - 使用这个策略,更新后的查询现在在我相当懦弱的笔记本电脑上运行大约 5 秒,数据库约为 200K节点和 .5M 关系。我添加了“persons”分组别名,以提醒“persons”在每个数组元素中都是不同的,但父构造会一遍又一遍地重复。你把它放在你手工种植的树上的什么地方很重要,但有能力做到这一点是很强大的。

    最重要的是,在 RETURN 语句中成熟地使用 JSON,让您可以对 Cypher 查询中的结果进行强大的控制。

    RETURN STATEMENT CONTENT:    
    <cypher_alias> 
          {.<cypher_alias_attribute>,
            ...,
            <grouping_alias>:
              (<cypher_alias>
                {.<cypher_alias_attribute,
                  ...
                }
              )
            ...
          }
    
    MATCH (j:J{uuid:'abcdef'})-[:J_S]->(s:S)<-[:N_S]-(n:N)-[:N_I]->(i:I), (j)-[:J_A]->(a:P)
    WHERE i.title IN ['title1', 'title2']
    WITH a,j, s, i, collect(n.description) as desc
    RETURN j{.title,persons:(a{.email,.name}), s_i_note:
     (s{.title, i_notes:(i{.title,desc})})}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多