煎饼大师:寻找缺失的食谱配料

假设你有一个包含食谱和配料、以及厨师及其当前厨房库存的数据库。
一位厨师(他的同事们敬佩并只称他为“煎饼大师”)想做一些煎饼。在开始之前,他需要知道他的厨房里是否有合适的配料。
我们首先创建配料。
MERGE (:Ingredient {name: "Flour"})
MERGE (:Ingredient {name: "Baking Powder"})
MERGE (:Ingredient {name: "Salt"})
MERGE (:Ingredient {name: "Sugar"})
MERGE (:Ingredient {name: "Egg"})
MERGE (:Ingredient {name: "Milk"})
MERGE (:Ingredient {name: "Butter"});
我们还描述了一个不错的煎饼食谱。
MERGE (flour:Ingredient {name: "Flour"})
MERGE (powder:Ingredient {name: "Baking Powder"})
MERGE (salt:Ingredient {name: "Salt"})
MERGE (sugar:Ingredient {name: "Sugar"})
MERGE (egg:Ingredient {name: "Egg"})
MERGE (milk:Ingredient {name: "Milk"})
MERGE (butter:Ingredient {name: "Butter"})
CREATE (pancake:Recipe {title: "Ultimate Pancake Recipe"})
CREATE (pancake)-[:requires_value]->(flour_val:Value)-[:is_part_of]->(flour)
CREATE (pancake)-[:requires_value]->(powder_val:Value)-[:is_part_of]->(powder)
CREATE (pancake)-[:requires_value]->(salt_val:Value {value: "Himalaya"})-[:is_part_of]->(salt)
CREATE (pancake)-[:requires_value]->(sugar_val:Value {value: "White"})-[:is_part_of]->(sugar)
CREATE (pancake)-[:requires_value]->(egg_val:Value {value: "Bio"})-[:is_part_of]->(egg)
CREATE (pancake)-[:requires_value]->(milk_val:Value {value: "Bio"})-[:is_part_of]->(milk)
CREATE (pancake)-[:requires_value]->(butter_val:Value {value: "Plain"})-[:is_part_of]->(butter)
RETURN *;
嗯,煎饼,好吃!
接下来,让我们描述煎饼大师在他的厨房里剩下的东西
CREATE (pancakeMaster:Chef {name: "Master of Pancakes"})
MERGE (flour:Ingredient {name: "Flour"})
MERGE (salt:Ingredient {name: "Salt"})
MERGE (sugar:Ingredient {name: "Sugar"})
MERGE (egg:Ingredient {name: "Egg"})
MERGE (milk:Ingredient {name: "Milk"})
MERGE (butter:Ingredient {name: "Butter"})
CREATE (pancakeMaster)-[:has_value]->(flour_val:Value)-[:is_part_of]->(flour)
CREATE (pancakeMaster)-[:has_value]->(salt_val:Value {value: "Fleur de Sel"})-[:is_part_of]->(salt)
CREATE (pancakeMaster)-[:has_value]->(sugar_val:Value {value: "Brown"})-[:is_part_of]->(sugar)
CREATE (pancakeMaster)-[:has_value]->(egg_val:Value {value: "Bio"})-[:is_part_of]->(egg)
CREATE (pancakeMaster)-[:has_value]->(milk_val:Value {value: "Bio"})-[:is_part_of]->(milk)
CREATE (pancakeMaster)-[:has_value]->(butter_val:Value {value: "Salty"})-[:is_part_of]->(butter)
RETURN *;
现在,我们已经拥有了所有数据,让我们看看我们是否准备好做煎饼
MATCH
(pancake:Recipe {title: "Ultimate Pancake Recipe"})-[:requires_value]->(req_value:Value)-[:is_part_of]->(ingredient:Ingredient)
OPTIONAL MATCH (ingredient)<-[:is_part_of]-(avail_value)<-[:has_value]-(pancakeMaster:Chef {name: "Master of Pancakes"})
RETURN ingredient.name AS ingredient, req_value, avail_value;
这已经不错了,但我们想只看到哪些配料是缺少的,或者哪种配料是错误的。为此,我们需要将所需配料与现有配料进行比较
MATCH
(pancake:Recipe {title: "Ultimate Pancake Recipe"})-[:requires_value]->(req_value:Value)-[:is_part_of]->(ingredient:Ingredient)
OPTIONAL MATCH (ingredient)<-[:is_part_of]-(avail_value)<-[:has_value]-(pancakeMaster:Chef {name: "Master of Pancakes"})
WITH ingredient, req_value, avail_value
WHERE avail_value IS NULL OR req_value.value <> avail_value.value
RETURN
ingredient.name AS ingredient,
CASE WHEN req_value.value IS NULL THEN "Any" ELSE req_value.value END AS required,
CASE WHEN avail_value IS NULL THEN "None" ELSE avail_value.value END AS available;
哎哟!咸黄油!如果能找到一些泡打粉和不咸黄油,我们就可以开始了。
MERGE (pancakeMaster:Chef {name: "Master of Pancakes"})
MERGE (powder:Ingredient {name: "Baking Powder"})
MERGE (butter:Ingredient {name: "Butter"})
WITH *
MATCH (pancakeMaster)-[:has_value]->(butter_val:Value)-[:is_part_of]->(butter)
SET butter_val.value = "Plain"
CREATE (pancakeMaster)-[:has_value]->(powder_val:Value)-[:is_part_of]->(powder)
RETURN *;
好了,现在厨师可以施展他的魔法了
MATCH (pancake:Recipe {title: "Ultimate Pancake Recipe"})-[:requires_value]->(req_value:Value)-[:is_part_of]->(ingredient:Ingredient)
OPTIONAL MATCH (ingredient)<-[:is_part_of]-(avail_value)<-[:has_value]-(pancakeMaster:Chef {name: "Master of Pancakes"})
WITH ingredient, req_value, avail_value
WHERE avail_value IS NULL OR req_value.value <> avail_value.value
RETURN
ingredient.name AS ingredient,
CASE WHEN req_value.value IS NULL THEN "Any" ELSE req_value.value END AS required,
CASE WHEN avail_value IS NULL THEN "None" ELSE avail_value.value END AS available;
如你所见,用 Neo4j 做饭真是太有趣了!
此页面是否有帮助?