whereIn(...)" を通じてデータをクエリします; 2. フィルターを通してデータをフィルターします; 3. ソートされたデータを "$data = $scoutModelsLists;" に設定します。"/> whereIn(...)" を通じてデータをクエリします; 2. フィルターを通してデータをフィルターします; 3. ソートされたデータを "$data = $scoutModelsLists;" に設定します。">

ホームページ >PHPフレームワーク >Laravel >Laravelのソート失敗問題を解決する方法

Laravelのソート失敗問題を解決する方法

藏色散人
藏色散人オリジナル
2022-01-06 15:09:212224ブラウズ

laravel ソート失敗の解決策: 1. "$query->whereIn(...)" を通じてデータをクエリする; 2. フィルターを通じてデータをフィルターする; 3. ソートされたデータを "$data = $" に設定するスカウトモデルリスト;"。

Laravelのソート失敗問題を解決する方法

この記事の動作環境: Windows 7 システム、Laravel バージョン 5.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の2つのメソッドがあり、前者はlaravelのコレクションを返し、後者はesのネイティブクエリ構造を返します。

2 つのコードの違いはこのブロックにあります

$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がソートされていますが、ここでもまたリセットされています。コンポーネントを変更した後に更新し、最終的にデータが返されたときにソートが追加されます。計画については記事の冒頭を参照してください。

とりあえず終わったので空いたら改良します。

最新の 5 つの Laravel ビデオ チュートリアル (推奨)

以上がLaravelのソート失敗問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。