I have a Neo4j database where i have ingredient nodes and recipe nodes. One recipe is connected to many nodes, so, for a simple cheddar sandwich, the recipe node would be connected to bread and cheddar cheese. What i wanted to achieve is to query all the recipes that contain for example at least pepper and salt so if my recipe has pepper, salt and ham it would match. What i have tried following this example is:
WITH ['pepper', 'salt'] as ingredients
MATCH (i:Ingredient)-[:INGREDIENT_OF]->(r:Recipe)
WHERE i.name in ingredients
WITH r, size(ingredients) as inputCnt, count(DISTINCT i) as cnt
WHERE cnt = inputCnt
RETURN r;
But it only matches the recipes where the exact ingredients are only pepper and salt. How can i achieve this?
CodePudding user response:
What your doing is querying for any recipe that contains at least sal or pepper. If you want your recipe to contain both you won't achieve that.
You can try this query:
MATCH (i:Ingredient)-[:INGREDIENT_OF]->(r:Recipe)
WITH r, collect(i.name) as recipeIngredients, ['salt', 'pepper'] as requiredIngredients
WHERE apoc.coll.containsAll(recipeIngredients, requiredIngredients)
RETURN r;
Here you first get all the recipe ingredients and then match those tan contain all your required ingredients. This solution uses the library apoc, make sure to have it installed.
CodePudding user response:
This looks like a very awkward way of doing this.
Most people would use a relational database and SQL.
The database would have a table that stores the relation "ingredient is used in recipe" which connects the ingredient ID to the recipe ID.
Then you write
SELECT recipe_id FROM used_in WHERE ingredient_id = ingedient1
AND ingredient_id = ingedient2;
Thats's it! You get a list of all the recipes that use both ingredients and possible others beside