Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-08-2018 01:39 AM
Hi!
I have a tree structure where ids are a list of parameters. For example ["A","B"]. IIf both these parameters are used as input it will fetch next node in tree and so on.
This is the code and an image of the nodes.
CREATE (t1:Tree {id:["A","B"]})
CREATE (t2:Tree {id:["C"]})
CREATE (t3:Tree {id:["D"]})
CREATE (t1)-[:INCLUSION]->(t2)
CREATE (t2)-[:INCLUSION]->(t3)
CREATE (t4:Tree {id:["E"]})
CREATE (t5:Tree {id:["F"]})
CREATE (t4)-[:INCLUSION]->(t5)
CREATE (t6:Tree {id:["D","F"]})
CREATE (t7:Tree {id:["X"]})
CREATE (t6)-[:INCLUSION]->(t7)
In this scenario with input ["A","B","E"] this will then include "C", "D" and "F". For the node A,B it means that both A and B needs to be part of input for the INCLUSION to be valid.
So when we have both "D" AND "F" it should also include "X".
Can this be done with one query?
I have tried to do the same query multiple times and if there is no new nodes discovered between two runs then I have completed discovery. But there must be a better solution right?
WITH ["A","B","E"] AS input
MATCH path=(t:Tree)-[:INCLUSION*]->(p) WHERE ALL(p IN t.id WHERE p IN input)
WITH input, COLLECT(DISTINCT p.id[0]) AS found
WITH found, input, FILTER(p IN found WHERE NOT p IN input) as foundnew
WITH input, found, foundnew, input + foundnew as output,
CASE (size(foundnew) > 0)
WHEN true THEN
{status: 'notdone', parameters: input + FILTER(p IN found WHERE NOT p IN input) }
ELSE
{status: 'done', parameters: input }
END AS res
WITH
CASE res.status = "notdone"
WHEN true THEN
res
END AS input,
CASE res.status = "done"
WHEN true THEN
res
END AS completed
WITH input.parameters AS input, COLLECT(completed) AS allcompleted
OPTIONAL MATCH path=(t:Tree)-[:INCLUSION*]->(p) WHERE ALL(p IN t.id WHERE p IN input)
WITH allcompleted, input, COLLECT(DISTINCT p.id[0]) AS found
WITH allcompleted, found, input, FILTER(p IN found WHERE NOT p IN input) as foundnew
WITH allcompleted, input, found, foundnew, input + foundnew as output,
CASE (size(foundnew) > 0)
WHEN true THEN
{status: 'notdone', parameters: input + FILTER(p IN found WHERE NOT p IN input) }
ELSE
{status: 'done', parameters: input }
END AS res
WITH allcompleted, res.status AS status, res.parameters AS parameters,
CASE res.status = "notdone"
WHEN true THEN
res
END AS input,
CASE res.status = "done"
WHEN true THEN
res
END AS completed
WITH input.parameters AS input, COLLECT(completed)+allcompleted AS allcompleted
OPTIONAL MATCH path=(t:Tree)-[:INCLUSION*]->(p) WHERE ALL(p IN t.id WHERE p IN input)
WITH allcompleted, input, COLLECT(DISTINCT p.id[0]) AS found
WITH allcompleted, found, input, FILTER(p IN found WHERE NOT p IN input) as foundnew
WITH allcompleted, input, found, foundnew, input + foundnew as output,
CASE (size(foundnew) > 0)
WHEN true THEN
{status: 'notdone', parameters: input + FILTER(p IN found WHERE NOT p IN input) }
ELSE
{status: 'done', parameters: input }
END AS res
WITH allcompleted, res.status AS status, res.parameters AS parameters,
CASE res.status = "notdone"
WHEN true THEN
res
END AS input,
CASE res.status = "done"
WHEN true THEN
res
END AS completed
WITH input.parameters AS input, COLLECT(completed)+allcompleted AS allcompleted
RETURN *
This will return this : (first run finds "C", "D", "F". Second run finds "X" and third run finds no new nodes thus the discovery is completed).
allcompleted
[
{
"status": "done",
"parameters": [
"A",
"B",
"E",
"C",
"D",
"F",
"X"
]
}
]
All the sessions of the conference are now available online