You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8 Eloquent如何查询符合总热量限制的随机分类食谱组合

Laravel 8 Eloquent实现符合热量上限的随机餐食组合

假设你的食谱数据对应Recipe模型(对应数据库表recipes,字段包括name、category、calories),可以通过以下两种方案实现需求:

方案一:PHP层生成并筛选组合(适合小数据量)

这种方式逻辑直观,适合每个分类下食谱数量不多的场景:

namespace App\Http\Controllers;

use App\Models\Recipe;
use Illuminate\Http\Request;

class MealPlanController extends Controller
{
    public function getRandomDailyMeal(int $calorieLimit = 1500)
    {
        // 获取各分类的食谱集合
        $snacks = Recipe::where('category', '零食')->get();
        $lunches = Recipe::where('category', '午餐')->get();
        $dinners = Recipe::where('category', '晚餐')->get();

        $validCombos = [];

        // 遍历所有可能的三餐组合,筛选热量达标的
        foreach ($snacks as $snack) {
            foreach ($lunches as $lunch) {
                foreach ($dinners as $dinner) {
                    $total = $snack->calories + $lunch->calories + $dinner->calories;
                    if ($total <= $calorieLimit) {
                        $validCombos[] = [
                            '零食' => $snack,
                            '午餐' => $lunch,
                            '晚餐' => $dinner,
                            '总热量' => $total
                        ];
                    }
                }
            }
        }

        // 无符合条件的组合时返回null,可根据业务调整
        if (empty($validCombos)) {
            return null;
        }

        // 随机返回一个有效组合
        return $validCombos[array_rand($validCombos)];
    }
}

方案二:数据库层直接查询筛选(适合大数据量)

通过数据库联表查询直接生成符合条件的组合,性能更优,尤其当食谱数量较多时:

namespace App\Http\Controllers;

use App\Models\Recipe;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;

class MealPlanController extends Controller
{
    public function getRandomDailyMealFromDb(int $calorieLimit = 1500)
    {
        $validCombo = Recipe::select(
            's.name as 零食名称', 's.calories as 零食热量',
            'l.name as 午餐名称', 'l.calories as 午餐热量',
            'd.name as 晚餐名称', 'd.calories as 晚餐热量',
            DB::raw('s.calories + l.calories + d.calories as 总热量')
        )
        ->from('recipes as s')
        ->where('s.category', '=', '零食')
        ->crossJoin('recipes as l')
        ->where('l.category', '=', '午餐')
        ->crossJoin('recipes as d')
        ->where('d.category', '=', '晚餐')
        ->whereRaw('s.calories + l.calories + d.calories <= ?', [$calorieLimit])
        ->inRandomOrder()
        ->first();

        return $validCombo;
    }
}

注意事项

  • 确保数据库中category字段的值与查询条件完全匹配(避免空格、大小写不一致等问题)
  • 若业务中分类可能新增,可将分类列表抽成配置数组,动态生成查询或循环逻辑,避免硬编码
  • 当无符合热量上限的组合时,需根据业务需求添加 fallback 逻辑(比如返回热量最接近上限的组合,或提示用户调整上限)

内容的提问来源于stack exchange,提问作者Rubyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:55