If the number of properties is greater than n, return from a highly connected graph in Neo4j -
this question direct extension of question asked here (and , earlier version here).
say have graph database looks this:
just previous questions asked, interesting thing someproperty
can 'yes' or 'no'.
in top row, 1 of 3 nodes has 'yes' property.
on bottom row, 3 nodes of 5 nodes have 'yes' property.
(slight philosophical sidenote: i'm starting suspect bad graph schema. why? because, within each set of nodes, each node in connected every other node. i'm not worried fact there 2 groups of nodes, fact when populate graph, talkback says, 'returned 530 rows.' think means created 530 subpaths within graph structure , seems overkill.)
anyway, problem i'm trying solve pretty same problem trying solve in earlier, simpler, more linear context here.
i want return full path of either of these disjoint graphs, whereas anywhere within said graph count occurrences of someproperty
greater 2.
i think common, simple problem. example, had 2 unrelated families, , says, "show me family has more 2 left handed people."
the super smart #cybersam recommended simpler incarnation of problem, along lines of:
match p=(a:person)-[:related_to*]->(b:person) not ()-[:related_to]->(a) , not (b)-[:related_to]->() , 2 < reduce(s = 0, x in nodes(p) | case when x. someproperty = 'yes' s + 1 else s end) return p;
...which works great if graph resembles more of straight line, , doesn't have each node in set related each other node.
i think reason why #cybersam's query won't handle more complex graph because there no terminal node.
(another philosophical sidenote: i'm starting come theories dense, intricate relationships in graph pose combinatorial problems, performance querying. think might due bidirectionality used cypher when querying?)
here's data. advice appreciate , helping me climb learning curve.
// match (n) detach delete n; create (albert:person {gender: 'male', name: 'albert', someproperty: 'yes'}) create (annie:person {gender: 'female', name: 'annie', someproperty: 'no'}) create (adrian:person {gender: 'female', name: 'adrian', someproperty: 'no'}) create (albert)-[:related_to]->(annie) create (annie)-[:related_to]->(albert) create (annie)-[:related_to]->(adrian) create (adrian)-[:related_to]->(annie) create (albert)-[:related_to]->(adrian) create (adrian)-[:related_to]->(albert) create (bill:person {gender: 'male', name: 'bill', someproperty: 'yes'}) create (barb:person {gender: 'female', name: 'barb', someproperty: 'yes'}) create (barry:person {gender: 'male', name: 'barry', someproperty: 'yes'}) create (bart:person {gender: 'male', name: 'bart', someproperty: 'no'}) create (bartholemu:person {gender: 'male', name: 'bartholemu', someproperty: 'no'}) create (bill)-[:related_to]->(barb) create (barb)-[:related_to]->(bill) create (barb)-[:related_to]->(barry) create (barry)-[:related_to]->(barb) create (barry)-[:related_to]->(bart) create (bart)-[:related_to]->(barry) create (bart)-[:related_to]->(bartholemu) create (bartholemu)-[:related_to]->(bart) create (bill)-[:related_to]->(bartholemu) create (bartholemu)-[:related_to]->(bill)
if families of people, easiest fix add :family node each relational group, so:
create (f:family) f match (a:person {name:"adrian"})-[:related_to*]->(b:person) merge (f:family)<-[:family]-(a) merge (f:family)<-[:family]-(b)
replace "adrian" "barry" create second family group.
that gives central :family node each family group. can pick family group has enough :person.someproperty = "yes" family members so:
// find families 2 or more :person.someproperty = "yes" match p = (f:family)<-[:family]-(psn:person) psn.someproperty = "yes" f, count(psn) cnt cnt > 2 // family members match (a:person)<-[r1:related_to]-(b:person)-[r2:related_to*]->(c) (a)-[:family]-(f) , = c // nodes in loop // report first record which'll have 2 // family members , relationships return a, r1, b, r2 limit 1
Comments
Post a Comment