我有一个问题:
start brand=node(62) match brand-[:CREATED_A]->(campaign:Campaign)<-->(node)
return DISTINCT brand,campaign,collect(node) ;
现在结果几乎像我想的那样回来了。我缺少的一件事是我希望拥有以下层次结构:
品牌有很多广告系列和广告系列都有很多节点连接到它,所以广告系列中的节点类型。
现在,广告系列会多次返回到每个返回的广告系列。
答案 0 :(得分:6)
我提供了一个Neo4j Gist来说明解决方案。简而言之,它使用文字地图来格式化数据,并使用两个收集来确保品牌不会多次出现。
MATCH
(brand:Brand)-[:CREATED_A]->(campaign:Campaign)<-->(node)
WITH
brand,
{
campaign : campaign,
nodes : COLLECT(node)
} AS campaigns
WITH
{
brand : brand,
campaigns : COLLECT(campaigns)
} AS brands
RETURN brands
这使得品牌出现一次,您的输出格式就会很好。
答案 1 :(得分:2)
Cypher是一种非常强大的语言。如果您知道要从节点获取哪些属性,您甚至可以返回类似json的输出,该输出也维护您在图形中实际建模的结构,您可以执行以下操作:
MATCH (brand:Brand)-[:CREATED_A]->(campaign:Campaign)<-->(node)
WITH
brand,
campaign as campaign,
COLLECT({
property1 : node.property1,
property2 : node.property2
}) as nodes
RETURN
{
name : brand.name,
logoUrl : brand.logoUrl,
campaigns : COLLECT({
name : campaign.name,
timestamp : campaign.timestamp,
nodes : nodes
})
} as brands
这将输出一个json结构,例如:
[
{
name : "my name",
logoUrl : "http://www...",
campaigns : [
{
name : "my campaign name",
timestamp : 1484172044462,
nodes : [
{
property1 : "property1",
property2 : "property2"
}
]
}
]
}
]
这实际上很好地反映了您的图表模型。
此外,由于您没有进行RETURN COLLECT(...),因此您可以迭代Record结果而不是获取第一个(也是唯一一个)记录并将所有行放入其中。当您处于嵌入式服务器的情况下,这可能是一种方便的方式,您可以在其中实际流式传输结果数据,而不是一次性检索它。
即使您没有任何馆藏(例如,一个广告系列只有一个节点),并且路径越来越深,这种方法也能很好地运作。 但是,当您的模型是树(或更糟的是图表)时,您可能会遇到挑战。
你可以在这个好主意中找到更多细节: https://gist.github.com/rherschke/9269173