Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
06-19-2020 08:39 PM
I have a requirement that in my database some nodes should have at most one relationship of a given type. For example, nodes with the label Heart
should be connected via has
to at most one node of label Body
.
Here's some test data to illustrate the issue:
CREATE (h:Heart {animal: "zebra"})
CREATE (b1:Body {animal: "zebra"})
CREATE (b2:Body {animal: "elephant"})
CREATE (b1)-[:has]->(h)
CREATE (b2)-[:has]->(h)
CREATE (h2:Heart {animal: "mouse"})
CREATE (b4:Body {animal: "mouse"})
CREATE (b5:Body {animal: "leopard"})
CREATE (b4)-[:has]->(h2)
CREATE (b5)-[:has]->(h2)
With the following query I can find all nodes with connections which don't respect this rule:
MATCH (n:Heart) WHERE (:Body)-[:has]-(n)-[:has]-(:Body) RETURN n
I'd like though, to write a statement to remove the "extra" relationships. Right now I've got a query to remove the nodes composing these "extra" relationships, but it also removes the nodes I'd like to keep (one of each).
MATCH (b1:Body)-[:has]-(n)-[:has]-(b2:Body) DETACH DELETE b1, b2
This also doesn't group relationships by the center node, so I can't really remove all nodes except one, as it would not have the desired effect.
Does anyone know how can I write a statement that will remove all "extra" relationships until only one relationship has
remains for each Heart
node? Preferably the oldest one.
Solved! Go to Solution.
06-24-2020 12:23 PM
Thank you everyone for your answer, but I think some of your didn't understand the issue properly.
The test data I wrote was only to illustrate the issue, it doesn't mean that's the only kind of data for which I want to implement such behavior.
I went with the following statement:
MATCH (:Body)-[r:has]->(h:Heart)
WITH h,COLLECT(r) AS rs
WHERE SIZE(rs)> 1
FOREACH (r IN rs[1..] |
DELETE r
)
It was a an answer to the same question I also wrote on StackOverflow.
Again, thank you all for taking your time to answer this question and have a good week!
06-20-2020 02:01 PM
I don`t understand but if you need to remove relationships
MATCH (b1:Body)-[R1:has]-(n)-[R2:has]-(b2:Body) DELETE R1, R2
Ok....
06-20-2020 09:59 PM
IF (and this is a big if) I'm understanding this correctly, you don't want a zebra heart attached to an elephant body. If that's the case, then I think something like this might work...
MATCH (b1:Body)-[:has]-(h:Heart)-[:has]-(b2:Body)
WHERE b1.animal <> b2.animal
return n
This should provide a resultset where the animal properties of the 2 attached bodies are not equal.
Is this what you're looking for?????
06-22-2020 12:33 PM
The answers below help you in getting rid of the non-wanted relations.
Additional you might want to look into constraints; https://neo4j.com/docs/cypher-manual/current/administration/constraints/
06-24-2020 12:23 PM
Thank you everyone for your answer, but I think some of your didn't understand the issue properly.
The test data I wrote was only to illustrate the issue, it doesn't mean that's the only kind of data for which I want to implement such behavior.
I went with the following statement:
MATCH (:Body)-[r:has]->(h:Heart)
WITH h,COLLECT(r) AS rs
WHERE SIZE(rs)> 1
FOREACH (r IN rs[1..] |
DELETE r
)
It was a an answer to the same question I also wrote on StackOverflow.
Again, thank you all for taking your time to answer this question and have a good week!
06-27-2020 02:34 AM
Thanks for documenting it here as well!
All the sessions of the conference are now available online