通八洲科技

Laravel Spatie 自定义筛选:基于关联模型最新记录的条件过滤

日期:2025-12-27 00:00 / 作者:聖光之護

本文介绍如何在 laravel 中使用 spatie query builder 实现“仅依据关联模型(如最后一次检查)的最新数据进行精准筛选”,解决 `wherehas` 无法限制子查询为单条记录的常见痛点。

在 Laravel 应用中,当需要根据关联模型的最新一条记录(而非任意匹配)进行筛选时,直接使用 whereHas() 配合 orderBy()->limit(1) 是无效的——因为 whereHas 的闭包内排序和限制对主查询无约束力,实际仍会匹配所有符合条件的关联记录,导致逻辑错误(例如:动物曾患病但最新检查已康复,却被误判为“生病”)。

正确方案需分三步完成:

  1. 获取每个动物最新检查记录的 ID(即按 animal_id 分组后取 MAX(id) 或 MAX(created_at) 对应的主键);
  2. 基于这些 ID 查询出真正“当前患病”的检查记录(disease_id IS NOT NULL);
  3. 提取对应 animal_id 并反向筛选动物主表

以下是经过优化、可直接使用的生产级实现:

groupBy('animal_id');

        // 步骤2:连接最新检查记录,并筛选 disease_id 非空的动物
        $sickAnimalIds = Examination::query()
            ->select('animal_id')
            ->whereIn('id', $subQuery->pluck('max_id'))
            ->whereNotNull('disease_id')
            ->pluck('animal_id');

        // 步骤3:主查询只保留这些动物
        $query->whereIn('id', $sickAnimalIds);
    }
}

关键改进说明:

⚠️ 注意事项:

通过该实现,系统将严格依据每只动物最近一次检查结果判断健康状态,确保筛选结果真实反映当前状况,完美契合医疗、IoT 设备状态监控等强时效性业务场景。