Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-13-2023 01:17 PM
Hi,
please consider the following graph:
CREATE (n0:Person {name: "Jack"})-[:ALLIED_WITH]->(n4:Person {name: "Theo"})-[:ENEMY_OF]->(n3:Person {name: "Paul"})<-[:PARTNER_OF]-(:Person {name: "Jim"})-[:ALLIED_WITH]->(n1:Person {name: "Mark"})-[:PARTNER_OF]->(:Person {name: "Bill"})<-[:ENEMY_OF]-(n0),
(n3)-[:ALLIED_WITH]->(n1),
(:Person {name: "Deb"})-[:PARTNER_OF]->(n4)
As you can see, I have 2 groups of nodes (yellow and green nodes). The nodes are linked within each group with "positive" relations ([PARTNER_OF] and [ALLIED_WITH]), while nodes of different groups have just "bad" relations ([ENEMY_OF], in the example).
Is it possible to create a constrain to prevent the creation of "positive" relations ('PARTNER_OF' and 'ALLIED_WITH', in this example) between nodes of different groups?
Thanks for your help!
01-13-2023 02:09 PM
Cypher does not have a constraint like this. You could try to use an apoc trigger to execute when a new relationship is created. You may be able to raise an exception if the new relationship relates two nodes in different groups.
https://neo4j.com/labs/apoc/4.4/background-operations/triggers/
https://neo4j.com/labs/apoc/4.4/overview/apoc.util/apoc.util.validate/
01-13-2023 02:11 PM
futher tto @glilienfield but Neo4j constraint functionality is described at
https://neo4j.com/docs/cypher-manual/4.4/constraints/
01-14-2023 02:10 AM
Thanks for your hints, but I'm afraid this is getting too complicated for me. Do you think changing the graph schema could help to simplify it?
01-15-2023 12:26 AM
What do you think about this solution?
//avoid enemies
PROFILE
// create wrong relation
MATCH (p1:Person {name: 'Deb'}), (p2:Person {name: 'Mark'})
MERGE (p1)-[r:PARTNER_OF]->(p2)
// check cluster
WITH p1, r
MATCH (p1)-[:PARTNER_OF|ALLIED_WITH*]-(ps)
WITH p1, r, collect(DISTINCT ps) as nodes
UNWIND [p1] + nodes as s
MATCH (s)-[:ENEMY_OF]-(e) WHERE NOT s.name = e.name AND e IN nodes
WITH r, collect(DISTINCT e) as enemies
FOREACH (i in
CASE WHEN not enemies = [] THEN [1] ELSE [] END | DELETE r
)
Could you suggest how to break the UNWIND loop as soon as line 11 MATCH finds the first result?
Thanks!
All the sessions of the conference are now available online