Laravel Eloquent实现多条件搜索:内容+分类筛选问题
解决Laravel中全文搜索结合分类筛选的问题
首先,咱们得确保你的Question模型已经正确定义了和Category的多对多关联——毕竟数据库里用了questions_categories中间表来关联两者。在app/Models/Question.php里添加上关联方法:
/** * 关联问题所属的分类 */ public function categories() { return $this->belongsToMany(Category::class, 'questions_categories'); }
接下来,你就可以在现有的全文搜索查询基础上,通过whereHas方法筛选出属于指定分类的问题了,这里分两种常见场景:
场景1:问题属于指定分类中的任意一个
如果只要问题在$tag_names数组的任意一个分类里就展示,用下面的代码:
$questions = Question::search($query_string) ->whereHas('categories', function ($query) use ($tag_names) { // 利用categories表name字段的唯一约束,匹配传入的分类名称数组 $query->whereIn('name', $tag_names); }) ->paginate(NUM_PER_PAGE);
场景2:问题必须属于所有指定分类
如果需要问题同时属于$tag_names里的所有分类(比如用户选了多个分类,要找交集),可以用两种方式实现:
方式一:循环叠加约束
$questionsQuery = Question::search($query_string); foreach ($tag_names as $tagName) { $questionsQuery->whereHas('categories', function ($query) use ($tagName) { $query->where('name', $tagName); }); } $questions = $questionsQuery->paginate(NUM_PER_PAGE);
方式二:用havingCount匹配分类数量
$questions = Question::search($query_string) ->whereHas('categories', function ($query) use ($tag_names) { $query->whereIn('name', $tag_names); }, '=', count($tag_names)) // 要求匹配到的分类数量等于传入的分类数组长度 ->paginate(NUM_PER_PAGE);
额外优化:处理空分类数组的情况
如果$tag_names可能为空(比如用户没选任何分类),记得加个判断,避免过滤掉所有结果:
$questionsQuery = Question::search($query_string); if (!empty($tag_names)) { $questionsQuery->whereHas('categories', function ($query) use ($tag_names) { $query->whereIn('name', $tag_names); }); } $questions = $questionsQuery->paginate(NUM_PER_PAGE);
这样就能完美结合你的PostgreSQL全文搜索和Laravel的分类筛选功能了~
内容的提问来源于stack exchange,提问作者Daniel Marques
相关产品推荐
相关产品推荐

