我目前正在使用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"})]
有任何提示可以解决这个问题吗?感谢
答案 0 :(得分:8)
在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"
}
]
}
]
}
]
}
答案 1 :(得分:2)
在这个重要主题上,这是一个非常有用的话题,我想在进一步探讨之后再添加一些想法。
首先,使用APOC“ toTree” proc有一些限制,或者更好的说是依赖项。架构的“树状”确实很重要。例如,上面的APOC调用中缺少LOVES关系,并且我理解为什么-使用“ toTree”时很难包含该关系-简单的添加有点像在层次结构中添加属性,而是作为关系。做起来不错,但混淆了简单的KNOWS树。要点是,一个很好的问题是“我如何应对此类挑战”。这个答复就是关于这个。
我确实建议您提高一些JSON技能,因为这将为您提供更精细的控制。就个人而言,我发现最初的探索有些痛苦。可能是因为我是XML的人:),但是一旦您弄清了所有的[,{和(),这实际上是有效地将最能描述为数据报告的强大方法。是很容易成为一类的东西,它提供了一种很好的方法将其推回应用程序。
相对于仅请求JSON,我发现perf对“ toTree”也是一个挑战。我在下面添加了一个非常简单的外观,以了解您的RETURN可能是什么样子。它遵循以下BN格式。我很乐意看到它的创建更加成熟,因为可能性千差万别,但这是我发现有用的东西,因此,我暂时将其发布。正如他们所说; “更多的潜水留给读者”?
我已经混淆了这些值,但这是一个实际的查询,我将它称为一个非常差的图形体系结构示例,在尝试访问有关其的整体报告时,其许多设计“错误”导致了一些严重的性能问题。图。如本例中所示,我继承的初始报告查询在服务器上花费了几分钟,并且无法在我的笔记本电脑上运行-使用此策略,更新的查询现在在大约200K db的我相当笨拙的笔记本电脑上运行大约5秒钟节点和.5M关系。我添加了“人”分组别名,以提醒每个数组元素中“人”将有所不同,但是父结构将一遍又一遍地重复。将其放在手工种植的树上的位置很重要,但是具有执行此功能的功能很强大。
底线是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})})}