Laravel中elasticSearch搜索时排序字段失效怎么办
Admin 2022-06-16 群英技术资讯 1240 次浏览
这篇文章将为大家详细讲解有关“Laravel中elasticSearch搜索时排序字段失效怎么办”的知识,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。laravel排序失效的解决办法:1、通过“$query->whereIn(...)”查询数据;2、通过filter过滤数据;3、设置排序好的数据为“$data = $scoutModelsLists;”。

本文操作环境:Windows7系统、Laravel5.8版、Dell G3电脑。
如何解决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 排序了,这里又重置了,为防止改组件后其他地方无法更新,所以在最后返回数据时加了排序处理,方案参考文章开头。
暂时告一段落,空了再完善。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
一.首先是PHP网页的编码1.php文件本身的编码与网页的编码应匹配a.如果欲使用gb2312编码,那么php要输出头:header(“Content-Type:text/html;charset=gb2312"),静态页面添加<metahttp-equiv="Content-Type"content="text/html;charset=gb2312">,所有文件的
PHP如何实现打包zip并下载功能?下文有实例供大家参考,对大家了解操作过程或相关知识有一定的帮助,而且实用性强,希望这篇文章能帮助大家,下面我们一起来了解看看吧。
PHP-验证名称以下代码将通过简单的方式来检测name字段是否包含字母和空格,如果name字段值不合法,将输出错误信息:$name=test_input($_POST[
在使用PHP的过程中也会遇到错误,那么我们该怎么处理这些错误呢?一起来通过本节的内容进行了解。在PHP中,默认的错误处理很简单。一条错误信息会被发送到浏览器,这条信息带有文件名、行号以及描述错误的信息。
如何用PHP实现抽奖功能?一般商家在搞活动时,我们总能看到各种抽奖,这些抽奖功能是怎样做的呢?下面就分享一个使用PHP写的抽奖功能实例,感兴趣的朋友就继续往下看吧。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008