We are using neo4j v4.
I have USER, COMPUTER, COMPANY nodes(IBM, HP, DELL etc),
How can I make the HP_IBM case work(i.e. when u.preference is HP_IBM, I want the computers manufactured by both HP and IBM)?
MATCH (u:USER {id: 101})
RETURN
CASE u.preference
WHEN 'HP' THEN [(n:computer)-[r: MANUFACTURED_BY]->(c:HP) | n]
WHEN 'IBM' THEN [(n:computer)-[r:ASSEMBELED_BY]->(c:IBM) | n]
WHEN 'DELL' THEN [(n:computer)-[r:ASSEMBELED_BY]->(c:DELL) | n]
WHEN 'HP_IBM' THEN xxxxxxx END
AS result;
Any other queries/approaches are welcome!
Your schema can be modeled in a better way. Instead of having company names as Node Labels, you can store them as a part of the company node property let's say name
. And instead of storing preferences as a concatenated String, you can store user-preferred companies in an array, like this: ["HP", "IBM"]
, now your cypher query becomes fairly simple, like this:
MATCH (u:USER {id: 101})
MATCH (n:computer)-[:MANUFACTURED_BY]->(c:Company)
WHERE c.name IN u.preferences
RETURN n;
If you want to keep the current schema itself, then try this:
MATCH (u:USER {id: 101})
RETURN
CASE u.preference
WHEN 'HP' THEN [(n:computer)-[r: MANUFACTURED_BY]->(c:HP) | n]
WHEN 'IBM' THEN [(n:computer)-[r:ASSEMBELED_BY]->(c:IBM) | n]
WHEN 'HP_IBM' THEN [(n:computer)-[r]->(c) WHERE ANY(x IN split(c.preference, '_') WHERE x IN labels(c)) | n] END
AS result;
Notice, that I have removed the relationship type from the path match because your relationship type varies with the company, so if your computer nodes are linked with the company, via a lot of distinct relationship types. This query might not work.