Laravel8 Scout Search 效果 懶得看詳細介紹可直接跳至簡單完整範例 ,但必須先安裝完成相關套件及申請Algolia 專案
介紹 Laravel Scout
提供了一個簡單的、基於驅動程序的解決方案,用於為您的Eloquent
模型添加全文搜索。使用模型觀察器,Scout 會自動使您的搜索索引與您的 Eloquent
記錄保持同步。
目前,Scout
附帶Algolia
和MeiliSearch
驅動程序。此外,Scout
包含一個“集合”驅動程序,專為本地開發使用而設計,不需要任何外部依賴項或第三方服務。此外,編寫自定義驅動程序很簡單,您可以使用自己的搜索實現自由擴展 Scout
。
安裝 安裝 Laravel Scout composer require laravel/scout
發佈配置 php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
最後,將Laravel\Scout\Searchable
特徵添加到您希望使其可搜索的模型中。此特徵將註冊一個模型觀察者,該觀察者將自動使模型與您的搜索驅動程序保持同步:
<?php namespace App \Models ;use Illuminate \Database \Eloquent \Model ;use Laravel \Scout \Searchable ;class Product extends Model { use Searchable ; }
申請 Algolia 到algolia 申請新的專案
選擇香港區域
複製專案 ID 以及 SECRET
使用 Algolia 驅動 使用 Algolia 驅動程序時,您應該在config/scout.php
中配置您的 Algolia id 和 secret key 。配置憑據後,您還需要通過 Composer 包管理器安裝 Algolia PHP SDK:
composer require algolia/algoliasearch-client-php
.env
檔案填入剛剛複製的專案 id 以及 key
ALGOLIA_APP_ID= ALGOLIA_SECRET=
queue 運行 queue 將允許 Scout 將您的模型信息同步到您的搜索索引的操作進行排隊,從而為您的應用程序的 Web 界面提供更好的響應時間。
配置隊列驅動程序後,將配置文件中的 queue 選項值設置 config/scout.php 為 true:
配置 配置模型索引 每個 Eloquent 模型都與給定的搜索“索引”同步,該索引包含該模型的所有可搜索記錄。換句話說,您可以將每個索引視為一個 MySQL 表。
<?php namespace App \Models ;use Illuminate \Database \Eloquent \Model ;use Laravel \Scout \Searchable ;class Product extends Model { use Searchable ; public function searchableAs ( ) { return 'productts_index' ; } }
配置可搜索數據 默認情況下,toArray
給定模型的整個表單將被持久化到其搜索索引。如果您想自定義與搜索索引同步的數據,您可以覆蓋toSearchableArray
模型上的方法:
<?php namespace App \Models ;use Illuminate \Database \Eloquent \Model ;use Laravel \Scout \Searchable ;class Post extends Model { use Searchable ; public function toSearchableArray ( ) { $array = $this ->toArray(); $array ['user' ] = $this ->user->name; return $array ; } }
配置模型 ID 默認情況下,Scout 將使用模型的主鍵作為存儲在搜索索引中的模型的唯一 ID/鍵。如果您需要自定義此行為,您可以覆蓋模型上的 getScoutKey 和 getScoutKeyName 方法:
<?php namespace App \Models ;use Illuminate \Database \Eloquent \Model ;use Laravel \Scout \Searchable ;class User extends Model { use Searchable ; public function getScoutKey ( ) { return $this ->email; } public function getScoutKeyName ( ) { return 'email' ; } }
本地開發 雖然您在本地開發過程中可以自由使用 Algolia
或 MeiliSearch
搜索引擎,但您可能會發現使用“collection
”引擎更方便。collection
引擎將對您現有數據庫中的結果使用“where”子句和收集過濾,以確定適用於您的查詢的搜索結果。使用此引擎時,沒有必要為您的可搜索模型“編制索引”,因為它們只會從您的本地數據庫中檢索。
要使用collection
引擎,您可以簡單地將 SCOUT_DRIVER 環境變量的值設置為collection
,或者直接在應用程序的 scout 配置文件中指定驅動程序:
一旦您將集合驅動程序指定為首選驅動程序,您就可以開始對您的模型執行搜索查詢。使用收集引擎時,不需要搜索引擎索引,例如Algolia
或 MeiliSearch
索引所需的索引。
索引 批量導入索引 使用scout:importArtisan
指令,該指令將所有現有記錄導入到您的搜索索引中:
php artisan scout:import "App\Models\Post"
flush
命令可用於從搜索索引中刪除模型的所有記錄:
php artisan scout:flush "App\Models\Post"
修改導入查詢 如果您想修改用於檢索所有模型以進行批量導入的查詢,您可以 makeAllSearchableUsing 在模型上定義一個方法。這是在導入模型之前添加可能需要的任何急切關係加載的好地方:
protected function makeAllSearchableUsing ($query ) { return $query ->with('author' ); }
添加記錄 一旦你已經添加了Laravel\Scout\Searchable
性狀的模型,所有你需要做的是save
或create
模型實例,它會自動被添加到您的搜索索引。如果您已將 Scout 配置為使用隊列,則此操作將由 queue 在後台執行:
use App \Models \Order ;$order = new Order;$order ->save();
搜尋 使用該 search 方法搜索模型。search 方法接受將用於搜索模型的單個字符串。然後,您應該將該 get 方法鏈接到搜索查詢上,以檢索與給定搜索查詢匹配的 Eloquent 模型:
use App \Models \Order ;$orders = Order::search('Star Trek' )->get();
如果您想在將原始搜索結果轉換為 Eloquent 模型之前獲得原始搜索結果,您可以使用以下 raw 方法:
$orders = Order::search('Star Trek' )->raw();
自定義索引 搜索查詢通常在模型searchableAs
方法指定的索引上執行。但是,您可以使用該within
方法來指定應該搜索的自定義索引:
$orders = Order::search('Star Trek' ) ->within('tv_shows_popularity_desc' ) ->get();
分頁 除了檢索模型集合之外,您還可以使用該paginate
方法對搜索結果進行分頁。此方法將返回一個Illuminate\Pagination\LengthAwarePaginator
實例,就像您對傳統的 Eloquent 查詢分頁一樣 :
use App \Models \Order ;$orders = Order::search('Star Trek' )->paginate();
您可以通過將數量作為第一個參數傳遞給paginate
方法來指定每頁檢索多少模型:
$orders = Order::search('Star Trek' )->paginate(15 );
檢索結果後,您可以使用 Blade 顯示結果並呈現頁面鏈接,就像對傳統的 Eloquent 查詢進行分頁一樣:
<div class ="container "> @foreach ($orders as $order ) {{ $order ->price }} @endforeach </div> {{ $orders ->links() }}
當然,如果您想以 JSON 形式檢索分頁結果,您可以直接從路由或控制器返回分頁器實例:
use App \Models \Order ;use Illuminate \Http \Request ;Route::get('/orders' , function (Request $request ) { return Order::search($request ->input('query' ))->paginate(15 ); });
簡單完整範例 .env 配置 SCOUT_QUEUE=true ALGOLIA_APP_ID=YOUR APP_ID ALGOLIA_SECRET=YOUR SECRET
Product Migration <?php use Illuminate \Database \Migrations \Migration ;use Illuminate \Database \Schema \Blueprint ;use Illuminate \Support \Facades \Schema ;class CreateProductsTable extends Migration { public function up ( ) { Schema::create('products' , function (Blueprint $table ) { $table ->id(); $table ->string('name' ); $table ->text('details' ); $table ->timestamps(); }); } public function down ( ) { Schema::dropIfExists('products' ); } }
Product Model <?php namespace App \Models ;use Illuminate \Database \Eloquent \Factories \HasFactory ;use Illuminate \Database \Eloquent \Model ;use Laravel \Scout \Searchable ;class Product extends Model { use HasFactory , Searchable ; protected $fillable = ['name' , 'details' ]; public function searchableAs ( ) { return 'products_index' ; } public function toSearchableArray ( ) { $array = $this ->toArray(); return $array ; } }
Product Controller public function index (Request $request ) { if ($request ->has('keyword' )) { $products = Product::search($request ->keyword) ->paginate(5 ); } else { $products = Product::paginate(5 ); } return view('products' , compact('products' )); }
路由 web.php Route::get('/products' , 'App\Http\Controllers\ProductController@index' )->name('products' );
View products.blade.php
<!DOCTYPE html > <html > <head > <title > Laravel 使用scount全文檢索範例</title > <link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity ="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin ="anonymous" /> </head > <body > <div class ="container" > <h3 class ="text-center" > Laravel 使用scount全文檢索範例</h3 > <form class ="form-inline mb-5" method ="GET" action ="{{ route('products') }}" > <input type ="text" class ="form-control" name ="keyword" /> <button class ="btn btn-outline-secondary" type ="submit" > 搜尋</button > </form > <table class ="table table-bordered" > <tr > <th width ="80px" > id</th > <th > 名稱</th > <th > 介紹</th > <th > 創建時間</th > </tr > @if($products->count()) @foreach($products as $key => $product) <tr > <td > {{ $product->id }}</td > <td > {{ $product->name }}</td > <td > {{ $product->details }}</td > <td > {{ $product->created_at->format('d-m-Y') }}</td > </tr > @endforeach @endif </table > {{ $products->links() }} </div > </body > </html >
導入索引 php artisan scout:import "App\Models\Product"
導入後可以發現 Algolia 多了相關的索引
run php artisan serve