解决laravel排序失效问题
laravel排序失效的解决办法:1、通过“$query->whereIn(...)”查询数据;2、通过filter过滤数据;3、设置排序好的数据为“$data = $scoutModelsLists;”。
如何解决laravel排序失效问题?
Laravel 5.8 scout7.0 使用 orderBy 排序失效解决方案
最近在使用 elasticSearch6.2.4 做搜索时发现,排序字段失效,所以在这记录下
先看下解决方案,话不多说,直接上代码
$list = Article::search($words)->orderBy('created_at','desc')->paginateRaw(10)->toArray();
$results = $list['data'];
if ($results['hits']['total'] === 0) {
return $this->model->newCollection();
}
$builder =new Builder(new static(),$this->model->newModelQuery());
$keys = collect($results['hits']['hits'])->pluck('_id')->values()->all();
$query = $this->newQuery();
if ($builder->queryCallback) {
call_user_func($builder->queryCallback, $query);
}
//查询数据
$scoutModelsLists = $query->whereIn(
$this->model->qualifyColumn($this->model->getKeyName()), $keys
)->orderBy('created_at','desc')->get();
//过滤数据
$scoutModelsLists->filter(function () use ($keys) {
return in_array($this->model->getKey(), $keys);
});
//这里为最终排序好的数据
$data = $scoutModelsLists;
问题分析
原来使用的查询语句为
$list = Article::search($words)->orderBy('created_at','desc')->paginate(10)->toArray();
上面查询语句虽然设置了排序字段,但是最终输出的时候却没有排序,经分析,在 ES 搜索结果里面的确是排了序,但最终输出时,ES 数据结构转化为集合时,并未加上排序字段
代码分析
文件 1: /vendor/laravel/scout/src/builder.php 约 261 行 - 305 行
仔细观察这个文件会有两个方法 paginate、paginateRaw ,前一个返回 laravel 集合,后一个返回 es 的原生查询结构,
这两者代码的不同点在于这块
$results = $this->model->newCollection($engine->map(
$this, $rawResults = $engine->paginate($this, $perPage, $page), $this->model
)->all());
文件 2:vendor/tamayo/laravel-scout-elastic/src/ElasticsearchEngine.php 211 行,map 方法,因为这里我们使用的是 ES 引擎,如果使用别的,可能有所不同,代码:
public function map(Builder $builder, $results, $model)
{
//无数据返回空集合
if ($results['hits']['total'] === 0) {
return $model->newCollection();
}
//获取所有键为_id的ES数据
//$keys = collect($results['hits']['hits'])->pluck('_id')->values()->all();
//转化ES数据并过滤
return $model->getScoutModelsByIds(
$builder, $keys
)->filter(function ($model) use ($keys) {
return in_array($model->getScoutKey(), $keys);
});
}
从代码看来,es 搜索出来有数据,则转化并过滤一下返回符合条件的集合,不满足直接返回空
文件 3: /vendor/laravel/scout/src/Searchable.php 约 171 行 getScoutModelsByIds 方法,代码
public function getScoutModelsByIds(Builder $builder, array $ids)
{
//加入软删除
$query = static::usesSoftDelete()
? $this->withTrashed() : $this->newQuery();
if ($builder->queryCallback) {
call_user_func($builder->queryCallback, $query);
}
// 重点这里,自改代码
// return $query->whereIn(
// $this->getScoutKeyName(), $ids
// )->orderBy('orderBy','desc')->get();
//官方代码
return $query->whereIn(
$this->getScoutKeyName(), $ids
)->get();
}
这个文件是重点,主要是这里最后返回的时候并没有加上 orderBy 排序字段,所以最后输出时虽然 es 排序了,这里又重置了,为防止改组件后其他地方无法更新,所以在最后返回数据时加了排序处理,方案参考文章开头。
暂时告一段落,空了再完善。
最新的五个Laravel视频教程(推荐)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tangbkbgh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01