Laravel8 Scout Search Example
Laravel8 Scout Search Example#
效果#
懶得看詳細介紹可直接跳至簡單完整範例,但必須先安裝完成相關套件安裝及申請 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:
SCOUT_QUEUE=true
配置#
配置模型索引#
每個 Eloquent 模型都與給定的搜索 “索引” 同步,該索引包含該模型的所有可搜索記錄。換句話說,您可以將每個索引視為一個 MySQL 表。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Product extends Model
{
use Searchable;
/**
* Get the name of the index associated with the model.
*
* @return string
*/
public function searchableAs()
{
// 在Algolia Index的名稱
return 'productts_index';
}
}
配置可搜索數據#
默認情況下,toArray
給定模型的整個表單將被持久化到其搜索索引。如果您想自定義與搜索索引同步的數據,您可以覆蓋 toSearchableArray
模型上的方法:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Post extends Model
{
use Searchable;
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// Customize the data array...
// 有一對一關聯可以這樣寫
$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;
/**
* Get the value used to index the model.
*
* @return mixed
*/
public function getScoutKey()
{
return $this->email;
}
/**
* Get the key name used to index the model.
*
* @return mixed
*/
public function getScoutKeyName()
{
return 'email';
}
}
本地開發#
雖然您在本地開發過程中可以自由使用 Algolia
或 MeiliSearch
搜索引擎,但您可能會發現使用 “collection
” 引擎更方便。collection
引擎將對您現有數據庫中的結果使用 “where” 子句和收集過濾,以確定適用於您的查詢的搜索結果。使用此引擎時,沒有必要為您的可搜索模型 “編制索引”,因為它們只會從您的本地數據庫中檢索。
要使用 collection
引擎,您可以簡單地將 SCOUT_DRIVER 環境變量的值設置為 collection
,或者直接在應用程序的 scout 配置文件中指定驅動程序:
SCOUT_DRIVER=collection
一旦您將集合驅動程序指定為首選驅動程序,您就可以開始對您的模型執行搜索查詢。使用收集引擎時,不需要搜索引擎索引,例如 Algolia
或 MeiliSearch
索引所需的索引。
索引#
批量導入索引#
使用 scout:importArtisan
指令,該指令將所有現有記錄導入到您的搜索索引中:
php artisan scout:import "App\Models\Post"
flush
命令可用於從搜索索引中刪除模型的所有記錄:
php artisan scout:flush "App\Models\Post"
修改導入查詢#
如果您想修改用於檢索所有模型以進行批量導入的查詢,您可以 makeAllSearchableUsing 在模型上定義一個方法。這是在導入模型之前添加可能需要的任何急切關係加載的好地方:
/**
* Modify the query used to retrieve models when making all of the models searchable.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
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
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('details');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
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>
<!-- Latest compiled and minified CSS -->
<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
相關資訊#
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: