In my memgraph database, I have nodes that are in a composite relationship. Hence there is one node (:Center) that -[:contains]-> one or more (:Component) nodes. I now want to SET one property for all (:Component) nodes, but the property's value depends on different attributes of its specific (:Center) node and also its own attributes.
What I came up with is something like:
MATCH (n:Component)
WITH collect(n) AS comps
FOREACH (comp IN comps | SET comp.level =
CASE WHEN all(c IN comps WHERE NOT c.zone = comp.zone OR
c.zone = comp.zone AND exists((c) <-[:contains]- (:Gateway)))
THEN 0
// level = 0 if all nodes with the same `zone` have a center
// with the label :Gateway
CASE WHEN any(c IN comps WHERE c.zone = comp.zone AND
exists((c) <-[:contains]- (center) WHERE center.name CONTAINS "special")
THEN 3
// level = 3 if one node with the same zone is part of a :Center
// with "special" in its name property
ELSE 1
END
)
Yet, memgraph tells me that it cannot use exists() in a SET clause and that an exists() can only take one relationship (which I thought I'd comply with). Also, apart from the query not working, I expect there to be a lot of nested looping which is probably not the best for performance.
Question 1: How can I SET the properties in a way that works?
Question 2: Can I optimize the query? (I also thought about pattern comprehension in the beginning but that didn't work either)
Question 3: All these issues make me doubt that the model is smartly built but I expected it to be best to rather use more nodes and relationships than to have one giant node with loads of complex data structures within...Is that true or should I change the model?
While I don't know memgraph or their particular implementation of openCypher, I might at least be able to give some potential insight regarding:
that an exists() can only take one relationship (which I thought I'd comply with)
I believe that the WHERE
part in
exists((c) <-[:contains]- (center) WHERE center.name CONTAINS "special")
might be the issue, as that is something more than just a relationship.
This is based on my experience with Neo4j and their Cypher though so it might differ from memgraph, but it would be my guess at least.
As a though experiment: would it be possible to calculate all the values or at least conditions separately to the SET, to split the SET and exists call? for example calculate something in one WITH clause and use that in the SET afterwards