Hello
I have a recipe database containing Recepies, Ingredients, etc...
I want to do the following query:
:param ingredients => ["potato", "tomato"];
:param preparationTimeRange => ["15"];
:param skillLevel => ["Easy"];
MATCH (node:Recipe)
WITH node
WHERE any(i in $ingredients WHERE exists((node)-[:CONTAINS_INGREDIENT]->(:Ingredient {name: i})))
OPTIONAL MATCH (node)
WHERE node.preparationTime in $preparationTimeRange
OPTIONAL MATCH (node)
WHERE node.skillLevel in $skillLevel
RETURN node
The problem is that it's ignoring the value of skillLevel.
I know it's because of the optional matching, but how to fix it :)
I want to skip this entire clause if there is no value for skillLevel, and take it correctly if there is.
MATCH (node:Recipe)-[:CONTAINS_INGREDIENT]->(i:Ingredient)
WHERE i.name in $ingredients
and node.preparationTimeRange in $preparationTimeRange
and (node.skillLevel is null or node.skillLevel in $skillLevel)
RETURN node, $ingredients, $preparationTimeRange, $skillLevel
You may consider setting the preparationTimeRange as integer in order to effectively establish a range query.
@Bennu solution is good. I just change it a bit to reflect the optional choices:
MATCH (node:Recipe)-[:CONTAINS_INGREDIENT]->(i:Ingredient)
WHERE i.name in $ingredients
and (NOT EXISTS(node.preparationTimeRange) OR (EXISTS(node.preparationTimeRange) AND (node.preparationTimeRange IN $preparationTimeRange))
and (NOT EXISTS(node.skillLevel) OR (EXISTS(node.skillLevel) AND (node.skillLevel IN $skillLevel))
RETURN node, $ingredients, $preparationTimeRange, $skillLevel