Если в таблице `recipe_product` пара (`recipe_id`, `product_id`) уникальная, то из данной таблицы можно удалить искусственный ключ `id` и сделать эту пару первичным ключом.
Поиск рецептов, в которые входят все указанные продукты:
SELECT `recipe_id`, COUNT(*) AS `count`
FROM `recipe_product`
WHERE (`product_id` = 1 AND `product_weight` > 100)
OR (`product_id` = 2 AND `product_weight` BETWEEN 200 AND 400)
OR (`product_id` = 3 AND `product_weight` < 10)
GROUP BY `recipe_id`
HAVING `count` = 3
Поиск рецептов, в которые входят все указанные продукты и ничего кроме них:
SELECT `recipe_id`, COUNT(*) AS `count`
FROM `recipe_product`
WHERE `recipe_id` NOT IN (SELECT `recipe_id` FROM `recipe_product` WHERE `product_id` NOT IN (1, 2, 3))
AND ((`product_id` = 1 AND `product_weight` > 100)
OR (`product_id` = 2 AND `product_weight` BETWEEN 200 AND 400)
OR (`product_id` = 3 AND `product_weight` < 10))
GROUP BY `recipe_id`
HAVING `count` = 3