使用 spatie/laravel-query-builder 和 teamtnt/laravel-scout-tntsearch-driver
Use spatie/laravel-query-builder with teamtnt/laravel-scout-tntsearch-driver
我尝试使用laravel tntsearch together with spatie query builder。基于 Spatie Query Builder 文档,我尝试按如下方式构建我的查询
if($request->has('kw')) {
$keyword = response()->json($request->get('kw'));
$query = Job::search($keyword);
} else {
$query = new Job();
}
$result = QueryBuilder::for($query)
->paginate()
->query();
因为 laravel tnt 搜索未返回 eloquent 对象,此查询将失败。
有没有办法将这两个包结合起来一起工作?
我完全按照您对 TNTSearch 驱动程序的尝试进行了操作,但我得出了一个艰难的结论,即 Scout 根本不支持默认 QueryBuilder 对象所支持的广泛查询处理。这是设计使然。如果您阅读 Scout 文档,它会清楚地表明您必须先执行搜索 ,然后再 应用您通常会应用的所有 filter/sort 查询。因此,可以这样想:搜索 > 过滤并对搜索结果进行排序。
话虽如此,有可能实现您想要的。它只需要 2 个查询而不是一个。也许有一天 Scout 会得到更好的支持。
我是这样做的:
设置一个变量来保存您的搜索结果 ID
$searchIds = blank($request->kw) ? [] : Job::search($this->search)->keys();
searchIds
现在是空数组或模型 ID 数组。现在您可以利用 Spatie 的 QueryBuilder 对象来应用您的过滤器和排序。
QueryBuilder::for(Job::class)
->allowedFilters([
// your filters go here
])
->allowedSorts([
// your sorts go here
])
->tap(function ($query) use ($searchIds) {
return empty($searchIds) ? $query : $query->whereIn('id', $searchIds);
})
->paginate();
在上面的示例中,我们使用 tap
方法有条件地链接到 whereIn
查询构建器方法。这是一种将查询编写得更简洁的更聪明的方法,但它等同于编写 QueryBuilder::for(Job::class)->whereIn('id', $searchIds)
。当没有搜索时,它会简单地忽略 whereIn
方法。
这会将您的 QueryBuilder 限制为仅与您的搜索匹配的结果,您可以将所有排序和过滤器应用于这些结果。
我尝试使用laravel tntsearch together with spatie query builder。基于 Spatie Query Builder 文档,我尝试按如下方式构建我的查询
if($request->has('kw')) {
$keyword = response()->json($request->get('kw'));
$query = Job::search($keyword);
} else {
$query = new Job();
}
$result = QueryBuilder::for($query)
->paginate()
->query();
因为 laravel tnt 搜索未返回 eloquent 对象,此查询将失败。 有没有办法将这两个包结合起来一起工作?
我完全按照您对 TNTSearch 驱动程序的尝试进行了操作,但我得出了一个艰难的结论,即 Scout 根本不支持默认 QueryBuilder 对象所支持的广泛查询处理。这是设计使然。如果您阅读 Scout 文档,它会清楚地表明您必须先执行搜索 ,然后再 应用您通常会应用的所有 filter/sort 查询。因此,可以这样想:搜索 > 过滤并对搜索结果进行排序。
话虽如此,有可能实现您想要的。它只需要 2 个查询而不是一个。也许有一天 Scout 会得到更好的支持。
我是这样做的:
设置一个变量来保存您的搜索结果 ID
$searchIds = blank($request->kw) ? [] : Job::search($this->search)->keys();
searchIds
现在是空数组或模型 ID 数组。现在您可以利用 Spatie 的 QueryBuilder 对象来应用您的过滤器和排序。
QueryBuilder::for(Job::class)
->allowedFilters([
// your filters go here
])
->allowedSorts([
// your sorts go here
])
->tap(function ($query) use ($searchIds) {
return empty($searchIds) ? $query : $query->whereIn('id', $searchIds);
})
->paginate();
在上面的示例中,我们使用 tap
方法有条件地链接到 whereIn
查询构建器方法。这是一种将查询编写得更简洁的更聪明的方法,但它等同于编写 QueryBuilder::for(Job::class)->whereIn('id', $searchIds)
。当没有搜索时,它会简单地忽略 whereIn
方法。
这会将您的 QueryBuilder 限制为仅与您的搜索匹配的结果,您可以将所有排序和过滤器应用于这些结果。