Laravel中三个不相关模型统一过滤并按创建日期排序返回求助
Laravel多模型统一过滤后合并排序解决方案
核心思路
先保留每个模型的查询构造器(不提前执行get()),统一追加过滤条件后再执行查询,最后合并结果并按创建日期排序。
步骤1:初始化查询构造器
先定义每个模型的查询构造器,带上需要预加载的关联,此时不要调用get():
$quickQuery = Model::with('user'); $simpleQuery = Models::with('user'); $suiviQuery = Modelss::with(['user', 'position']);
步骤2:统一应用过滤条件
针对所有查询构造器追加相同的过滤规则,示例如下:
// 示例1:过滤7天内创建的数据 $filterDate = now()->subDays(7); $quickQuery->where('created_at', '>=', $filterDate); $simpleQuery->where('created_at', '>=', $filterDate); $suiviQuery->where('created_at', '>=', $filterDate); // 示例2:按关键词模糊匹配(假设三个模型都有title/content字段) $keyword = request('keyword'); if ($keyword) { $filterCallback = function($q) use ($keyword) { $q->where('title', 'like', "%{$keyword}%") ->orWhere('content', 'like', "%{$keyword}%"); }; $quickQuery->where($filterCallback); $simpleQuery->where($filterCallback); $suiviQuery->where($filterCallback); }
步骤3:执行查询并合并排序
执行所有查询,合并结果集后按创建日期排序:
// 执行查询获取模型集合 $quickItems = $quickQuery->orderByDesc('id')->get(); $simpleItems = $simpleQuery->orderByDesc('id')->get(); $suiviItems = $suiviQuery->orderByDesc('id')->get(); // 合并三个集合 $merged = $quickItems->merge($simpleItems)->merge($suiviItems); // 按创建日期倒序排序,重置集合索引 $sorted = $merged->sortByDesc('created_at')->values();
性能优化方案(大数据量场景)
如果数据量较大,内存合并会有性能瓶颈,可以用数据库层面的UNION查询(需保证三个模型表的字段兼容):
// 构造联合查询,选择相同字段并标记数据类型 $unionQuery = $quickQuery->select( 'id', 'title', 'created_at', 'user_id', DB::raw("'quick' as model_type") ) ->union($simpleQuery->select( 'id', 'title', 'created_at', 'user_id', DB::raw("'simple' as model_type") )) ->union($suiviQuery->select( 'id', 'title', 'created_at', 'user_id', DB::raw("'suivi' as model_type") )); // 执行查询并排序 $sortedResults = $unionQuery->orderByDesc('created_at')->get();
注意:UNION查询返回的是标准集合而非Eloquent模型,关联数据需要手动处理。
内容的提问来源于stack exchange,提问作者landry moutongo
相关产品推荐
相关产品推荐

