@@ -26,21 +26,23 @@ public function __construct(private DatabaseManager $db)
26
26
public function getCocktailsByIngredients (array $ ingredientIds , ?int $ limit = null , bool $ useParentIngredientAsSubstitute = false , bool $ matchComplexIngredients = true ): Collection
27
27
{
28
28
// Resolve complex ingredients
29
+ // Basically, goes through all ingredients to match ($ingredientIds) and check if they can create complex ingredients
30
+ // If they can, that ingredient is added to the list of ingredients to match
29
31
if ($ matchComplexIngredients ) {
30
- $ complexIngredientsSubquery = ComplexIngredient:: select ( ' main_ingredient_id ' , DB :: raw ( ' COUNT(DISTINCT ingredient_id) as cnt ' ))
31
- -> whereIn ( ' ingredient_id ' , $ ingredientIds )
32
- -> groupBy ( ' main_ingredient_id ' );
33
-
34
- $ matchedComplexMainIngredientIds = DB :: table ( DB :: raw ( " ( { $ complexIngredientsSubquery -> toSql ()} ) as IngredientCount " ))
35
- -> mergeBindings ( $ complexIngredientsSubquery -> getQuery ())
36
- -> where ( ' cnt ' , count ( $ ingredientIds ))
37
- -> pluck ( ' main_ingredient_id ' );
38
-
39
- foreach ( $ matchedComplexMainIngredientIds as $ additionalId ) {
40
- if (! in_array ( $ additionalId , $ ingredientIds )) {
41
- $ ingredientIds [] = $ additionalId ;
42
- }
43
- }
32
+ $ rawQuery = " WITH RECURSIVE IngredientChain AS (
33
+ SELECT id AS matched_ingredient
34
+ FROM ingredients
35
+ WHERE id IN ( " . implode ( ' , ' , $ ingredientIds ) . " )
36
+ UNION
37
+ SELECT ci.main_ingredient_id AS matched_ingredient
38
+ FROM complex_ingredients ci
39
+ INNER JOIN IngredientChain ic ON ci.ingredient_id = ic.matched_ingredient
40
+ )
41
+ SELECT DISTINCT matched_ingredient
42
+ FROM IngredientChain; " ;
43
+
44
+ $ additionalIngredients = collect ( DB :: select ( $ rawQuery ))-> pluck ( ' matched_ingredient ' );
45
+ $ ingredientIds = array_merge ( $ ingredientIds , $ additionalIngredients -> toArray ());
44
46
}
45
47
46
48
$ query = $ this ->db ->table ('cocktails AS c ' )
0 commit comments