Laravel Scout TNTSearch调用search()报错及多过滤需求问题
解决Laravel Scout TNTSearch与自定义筛选协同的问题
咱们先搞定那个Call to undefined method Illuminate\Database\Eloquent\Builder::search()错误,再调整逻辑让筛选和搜索正常协同,顺便修复你代码里的几个小问题。
1. 错误根源:Scout的search()调用顺序不对
Laravel Scout的search()是模型的静态方法,它返回的是Laravel\Scout\Builder实例,而非Eloquent Builder。你现在先调用filter()(返回Eloquent Builder)再调用search(),相当于在Eloquent Builder上调用不存在的方法,自然会报错。
正确的做法是先调用search()获取Scout Builder,再通过query()方法拿到底层Eloquent Builder,然后应用自定义筛选:
// 调整后的控制器代码 $posts = Post::search($request->input('query')) ->query(function ($query) use ($request, $filters) { $query->filter($filters); // 在搜索结果基础上应用自定义筛选 }) ->paginate(10); // 注意:paginate(0)会返回空分页,建议改成合理数值比如10 $posts->load(['postcategory.section','author']); if($posts->isEmpty()) { return response()->json([ 'message' => 'No results found', ], 404); // 没找到资源用404状态码更合理,500是服务器错误 } return response()->json([ 'message' => 'Results found', 'posts' => $posts, ]);
2. 修复QueryFilters里的语法错误
你的sort()方法有两个明显错误,会导致筛选失效:
- PHP获取数组长度要用
count($sortArray),不是$sortArray.length(这是JS写法) $this->bulider拼写错误,应为$this->builder
修复后的sort()方法:
public function sort($term) { $sortArray = explode(",", $term); // 修正循环条件和数组长度获取方式 for($i = 0; $i < count($sortArray); $i++) { $sortItem = $sortArray[$i]; $sortBy = substr_replace($sortItem, "", -1); $sortChar = substr($sortItem, -1); $sortOrder = $sortChar == '+' ? 'ASC' : 'DESC'; // 修复拼写错误:bulider → builder $this->builder->orderBy($sortBy, $sortOrder); } return $this->builder; }
3. 确保模型配置正确
确认Post模型同时引入Scout的Searchable和自定义的Filterable trait:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; use App\Filters\Filterable; class Post extends Model { use Searchable, Filterable; // 定义Scout要搜索的字段 public function toSearchableArray() { return [ 'id' => $this->id, 'title' => $this->title, // 添加其他需要全文搜索的字段 ]; } }
4. 额外优化:避免搜索参数干扰筛选
你的QueryFilters的filters()方法返回所有请求参数,会导致Scout的query参数被传入筛选逻辑,触发不存在的方法。建议排除搜索参数:
public function filters() { // 只保留筛选参数,排除搜索关键词 return $this->request->except('query'); }
这样调整后,Scout的全文搜索会先执行,随后在搜索结果基础上应用你的自定义筛选、排序规则,最后分页返回结果,两者就能完美协同工作了。
内容的提问来源于stack exchange,提问作者gabogabans
相关产品推荐
相关产品推荐

