Reputation: 1125
I have a query:
start brand=node(62) match brand-[:CREATED_A]->(campaign:Campaign)<-->(node)
return DISTINCT brand,campaign,collect(node) ;
Right now the results coming back almost as I wanted. The one thing that I'm missing is that I want to have a hierarchy of the following:
brand has a lot of campaigns and campaigns has a lot of node connected to it so kind of nodes in campaign in brand.
Right now the campaign is coming back multiple time to each campaign that is returning.
Upvotes: 3
Views: 3620
Reputation: 61
Cypher is a very powerful language. If you know which properties you want to get from the nodes you can even return a json-like output that maintains also the structure you actually modelled in your graph, you can do something like this:
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
this will output a json structure such as:
[
{
name : "my name",
logoUrl : "http://www...",
campaigns : [
{
name : "my campaign name",
timestamp : 1484172044462,
nodes : [
{
property1 : "property1",
property2 : "property2"
}
]
}
]
}
]
That actually reflects nicely your graph model.
Moreover, since you are not doing RETURN COLLECT(...) this allows you to iterate over your Record result instead of getting the first (and only one) record and getting all the rows into it. This might be a convenience way when you are in situation like embedded server in which you can actually stream your result data instead of retrieve it in one shot.
This approach works pretty well even if you don't have any collections (eg one campaign has only one node) and also if the path gets deeper. However you may encounter challenges when your model is a tree (or worse, a graph).
You can find more details in this nice gist: https://gist.github.com/rherschke/9269173
Upvotes: 4
Reputation: 19211
I have provided a Neo4j Gist that illustrates a solution. In short it uses literal maps to format the data and two collects to make sure that the brands does not occur multiple times.
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
This makes the brands occur once and you get a nice format for your output.
Upvotes: 8