Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-26-2021 03:35 PM
Hi All
I'm sorry, I'm junior on graph
Let's suppose the graph of normal person is figure1
John is describe as picture 2
Is it possible with Neo4J, to match a graph ( John) against another graph the defined a normal person (picture 1) and identify the gap?
Thanks for your help
Solved! Go to Solution.
03-30-2021 04:08 PM
I created your scenario:
Try this:
MATCH (a:Person)-[*..]->()
WHERE a.name = "P"
CALL apoc.path.spanningTree(a, {maxLevel: 2}) YIELD path
with nodes(path) as a1
unwind a1 as a2
with collect(distinct labels(a2)) as lbl1
MATCH (b:Person)-[*..]->()
WHERE b.name = "John"
CALL apoc.path.spanningTree(b, {maxLevel: 2}) YIELD path
with lbl1, nodes(path) as b1
unwind b1 as b2
with lbl1, collect(distinct labels(b2)) as lbl2
with apoc.coll.subtract(lbl1, lbl2) AS diff
return diff
Result: ["Belly"]
03-28-2021 11:40 AM
there are two helper functions in APOC, that may be worth looking at, I don't think either are a drop in solution for this, but could be useful in building a solution
03-29-2021 06:46 AM
Thanks @Joel for your response.
Do you think pattern can help on the issue?
My understanding is that pattern can help design a structure of the database. I'm not sure if my understanding is correct or not.
03-29-2021 10:28 AM
I'm not sure what you mean, but the most obvious (but quite possibly not the best) way to compare is to programmatically walk the "normal" person graph, and an "individual" person graph in parallel, taking note of what's missing in the individual's graph. Starting at the Person node and probably I'd use a breadth first walk. e.g.
Normal has a person node, individual does as well, check same
Normal has child nodes of head, trunk and limbs, this individual (john) does as well, check same
Normal has face and skull child nodes for head, individual does as well, check same
Normal has belly and chest child nodes under trunk, individual has only chest, check John is missing belly node
Normal has feet and hand child nodes under limbs, individual does as well, check same
total result: John is missing the node belly at person->trunk->, maybe return it as person->trunk->belly not sure what you want as output though.
Two notes
03-30-2021 02:25 PM
Yes, I'm comparing the structure, not the values
I took a simply example to explain the problem. The graph I'm working on has around 1000 nodes
03-30-2021 02:30 PM
Thanks for your help @Joel
I think it might be difficult to do this in a graph with 1000 nodes.
Does anyone knows how schema or patterns works?
03-30-2021 02:05 PM
Goodevening,
Maybe you can use the power of the relations within Neo4j.
A don 't know exactly how to built.
But do something like compare the relations between person and John.
You could make the relations of person as a reference by naming them. And then at creation of John use the same names of person relations. Then get the relations used in person and compare them with the relations used in John.
Yours kindly,
Omer
03-30-2021 02:33 PM
Hello @omerule
Thanks for your answer
I'm not very sure, I got your point.
I'm trying to check whether two different graphs have the same structure
03-30-2021 02:50 PM
Not sure here. but if we think the structure is created by the relations (The belly of John could be there but is not attached then the relationship is important. ).
If possible you could make the relationship of person as a convention something like "node2node". Then use that methode in the relations used with John. And then get the relations form person (reference structure?) And compare those relations with the ones used in John.
03-30-2021 04:08 PM
I created your scenario:
Try this:
MATCH (a:Person)-[*..]->()
WHERE a.name = "P"
CALL apoc.path.spanningTree(a, {maxLevel: 2}) YIELD path
with nodes(path) as a1
unwind a1 as a2
with collect(distinct labels(a2)) as lbl1
MATCH (b:Person)-[*..]->()
WHERE b.name = "John"
CALL apoc.path.spanningTree(b, {maxLevel: 2}) YIELD path
with lbl1, nodes(path) as b1
unwind b1 as b2
with lbl1, collect(distinct labels(b2)) as lbl2
with apoc.coll.subtract(lbl1, lbl2) AS diff
return diff
Result: ["Belly"]
All the sessions of the conference are now available online