0
votes

Hi im using neo4j to create a recipe database. There are recipe nodes, and ingredient nodes, and pantry nodes and contains relationship. Generally there are many recipes that contain many ingredients and only one or so pantries which contain a number of ingredients. I want to know what recipes contain the ingredients i have in the pantry. It would also be cool if i could order the recipes results such that the recipe with the most ingredient are display first

MATCH (pantry_a:Pantry {name: "pantry_a"})-[:Contains]->(i:Ingredient) 
WITH COLLECT(i) AS pantry_ingredients
MATCH (r:Recipe)-[:Contains]->(i:Ingredient)
WITH pantry_ingredients, r, COLLECT(i) AS other_ingredients 
WHERE ALL(x IN pantry_ingredients WHERE x IN other_ingredients)
RETURN r.name

But it returns nothing. Would appreciate any help

Cheers

1

1 Answers

1
votes

[UPDATED]

If you only want to find the recipes whose ingredients are all contained in the specified pantry, you were very close. The only real problem was in your WHERE clause, which was checking that all pantry ingredients are in the recipe. You actually want to check for the opposite (i.e., that all recipe ingredients are in the pantry).

The following query should work for you. It also returns the recipes with the most ingredients first.

MATCH (:Pantry {name: "pantry_a"})-[:Contains]->(i:Ingredient)
WITH COLLECT(i) AS pantry_ingredients
MATCH (r:Recipe)-[:Contains]->(i:Ingredient)
WITH pantry_ingredients, r, COLLECT(i) AS recipe_ingredients
WHERE ALL(x IN recipe_ingredients WHERE x IN pantry_ingredients)
RETURN r.name
ORDER BY SIZE(recipe_ingredients) DESC;

On the other hand, if you want all recipes that require one or more ingredients from the specified pantry, and sort the results by the number of ingredients found in that pantry, this should work:

MATCH (:Pantry {name: "pantry_a"})-[:Contains]->(i:Ingredient)
WITH COLLECT(i) AS pantry_ingredients
MATCH (r:Recipe)-[:Contains]->(i:Ingredient)
WHERE i IN pantry_ingredients
WITH r, COLLECT(i) AS recipe_ingredients_in_pantry
RETURN r.name
ORDER BY SIZE(recipe_ingredients_in_pantry) DESC;