Laravel 8预加载中WhereNotIn无法正常过滤问题求助
问题分析与解决思路
你的代码逻辑存在核心问题,导致whereNotIn达不到预期的反向过滤效果:
- 原代码中
whereHas('documents', function($query) { $query->whereNotIn(...) })的逻辑是:只要这个人有至少一个文档不在排除列表里,就会被保留。 - 现实中大部分人员的文档不会全部属于排除列表,所以几乎所有公司都满足这个条件,自然返回了全部数据。
正确的逻辑应该是:这个人没有任何文档属于排除的类型,对应两种简洁的实现方式:
方案一:使用whereDoesntHave(推荐)
whereDoesntHave是Laravel专门用于筛选「不存在符合条件关联记录」的方法,正好匹配需求:
$callback = function ($query) { $query->whereDoesntHave('documents', function($query) { $query->whereIn('document_type_id', $this->negative_documents); }); }; $companies = $companies->whereHas('people', $callback)->with('people', $callback);
这段代码会筛选出没有任何文档属于排除类型的人员,进而得到对应的公司,完美对应whereIn逻辑的反向结果。
方案二:用whereHas结合计数判断
如果需要额外限制人员必须存在文档(排除无文档的人员),可以通过统计符合排除条件的文档数量为0来实现:
use Illuminate\Support\Facades\DB; $callback = function ($query) { $query->whereHas('documents', function($query) { $query->whereIn('document_type_id', $this->negative_documents); }, '=', 0); }; $companies = $companies->whereHas('people', $callback)->with('people', $callback);
这里whereHas的第三个参数指定「符合排除条件的文档数量等于0」,逻辑和方案一一致,但写法稍繁琐。
内容的提问来源于stack exchange,提问作者Ivan Kamas
相关产品推荐
相关产品推荐

