全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Laravel Spatie 自定义过滤器:按关联模型最新记录筛选数据

本文介绍如何使用 laravel spatie query builder 实现基于关联模型(如 `examinations`)**最新一条记录**(而非任意记录)的精准过滤,解决 `wherehas` 无法限制“最后一条”的常见误区。

在使用 Spatie Query Builder 进行关系过滤时,一个典型误区是误以为 whereHas(...->orderBy()->limit(1)) 能筛选出“拥有最新检查且患病”的动物——但实际上,whereHas 中的 orderBy 和 limit 在子查询中被忽略(Eloquent 不支持在 whereHas 子查询中使用排序与分页),导致它仍会匹配任意一条满足条件的检查记录,而非严格意义上的“最后一次”。

要真正实现“仅当最新一次检查的 disease_id 非空时才视为生病”,需采用两阶段查询策略:先定位每只动物的最新检查记录 ID,再基于这些 ID 精确过滤。

以下是推荐的、高效且可读性强的实现方式(已适配 Laravel 9+ 及 Spatie Query Builder v5+):

select('animals.*'); // 显式选择主表字段,避免后续 pluck 异常
        $animalIdsWithLatestExam = $query
            ->withMax('examinations', 'id')
            ->get()
            ->filter(fn ($animal) => $animal->examinations_max_id !== null)
            ->pluck('examinations_max_id');

        // Step 2: 查询这些最新 examination ID 对应的记录,并筛选 disease_id != null
        $sickAnimalIds = Examination::query()
            ->whereIn('id', $animalIdsWithLatestExam)
            ->whereNotNull('disease_id')
            ->pluck('animal_id');

        // Step 3: 主查询仅保留符合条件的 animal.id
        $query->whereIn('id', $sickAnimalIds);
    }
}

关键说明:

  • withMax('examinations', 'id') 利用 Eloquent 的聚合关系,为每个 Animal 附加 examinations_max_id 字段(即其最新检查 ID),无需 N+1 查询,性能优秀
  • filter(...->examinations_max_id !== null) 排除从未做过检查的动物,避免空值干扰;
  • whereNotNull('disease_id') 比 != null 更语义清晰且兼容 SQL 标准(尤其在 PostgreSQL 中更可靠);
  • 整个流程逻辑清晰、可测试、易维护,不依赖原始 SQL,保持 Laravel 生态一致性。

⚠️ 注意事项:

  • 确保 examinations 表的 animal_id 字段已建立索引(INDEX animal_id),否则 whereIn + 子查询可能影响性能;
  • 若数据量极大(>100k 动物),建议将此逻辑移至数据库视图或使用原生 JOIN 优化(例如通过 ROW_NUMBER() OVER (PARTITION BY animal_id ORDER BY created_at DESC));
  • 此过滤器默认启用,需在控制器中显式注册:
    $animals = QueryBuilder::for(Animal::class)
        ->allowedFilters(Filter::custom('sick', SickAnimalsFilter::class))
        ->get();

通过该方案,你将精准获得“当前生病”的动物列表——即其最后一次检查明确关联了疾病,彻底规避历史病历造成的误判。


# php  # laravel  # app  # sql  # NULL  # Filter  # postgresql  # 数据库  # 而非  # 每只  # 做过  # 分页  # 不支持  # 将此  # 你将  # 时才  # 如何使用  # 符合条件 


相关文章: 如何在服务器上配置二级域名建站?  如何确保西部建站助手FTP传输的安全性?  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  建站之星安装后如何配置SEO及设计样式?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何通过服务器快速搭建网站?完整步骤解析  Swift开发中switch语句值绑定模式  定制建站如何定义?其核心优势是什么?  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  重庆市网站制作公司,重庆招聘网站哪个好?  ,网页ppt怎么弄成自己的ppt?  制作企业网站建设方案,怎样建设一个公司网站?  合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?  北京建设网站制作公司,北京古代建筑博物馆预约官网?  建站168自助建站系统:快速模板定制与SEO优化指南  中山网站推广排名,中山信息港登录入口?  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  建站之星3.0如何解决常见操作问题?  建站主机是什么?如何选择适合的建站主机?  如何选择域名并搭建高效网站?  昆明高端网站制作公司,昆明公租房申请网上登录入口?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  陕西网站制作公司有哪些,陕西凌云电器有限公司官网?  如何快速上传建站程序避免常见错误?  建站之星微信建站一键生成小程序+多端营销系统  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  简历在线制作网站免费,免费下载个人简历的网站是哪些?  建站之星价格显示格式升级,你的预算足够吗?  建站主机如何选?高性价比方案全解析  南平网站制作公司,2025年南平市事业单位报名时间?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  模具网站制作流程,如何找模具客户?  网页设计网站制作软件,microsoft office哪个可以创建网页?  如何做静态网页,sublimetext3.0制作静态网页?  制作公司内部网站有哪些,内网如何建网站?  网站代码制作软件有哪些,如何生成自己网站的代码?  如何彻底卸载建站之星软件?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  北京制作网站的公司,北京铁路集团官方网站?  制作农业网站的软件,比较好的农业网站推荐一下?  如何在VPS电脑上快速搭建网站?  网站制作的步骤包括,正确网址格式怎么写?  如何通过云梦建站系统实现SEO快速优化?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  如何选择最佳自助建站系统?快速指南解析优劣  如何在新浪SAE免费搭建个人博客?  制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?  建站主机与服务器功能差异如何区分? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。