# Laravel Scout
- [簡介](#introduction)
- [安裝](#installation)
- [隊列](#queueing)
- [驅動之前](#driver-prerequisites)
- [配置](#configuration)
- [配置模型索引](#configuring-model-indexes)
- [配置可搜索的數據](#configuring-searchable-data)
- [索引](#indexing)
- [批量導入](#batch-import)
- [添加記錄](#adding-records)
- [更新記錄](#updating-records)
- [刪除記錄](#removing-records)
- [暫停索引](#pausing-indexing)
- [搜索](#searching)
- [Where 語句](#where-clauses)
- [分頁](#pagination)
- [自定義引擎](#custom-engines)
<a name="introduction"></a>
## 簡介
Laravel Scout 為 [Eloquent 模型](/docs/{{version}}/eloquent) 的全文搜索提供了一個簡單的、基于驅動程序的解決方案。使用模型觀察員,Scout 會自動同步你的搜索索引和 Eloquent 記錄。
目前,Scout 自帶了一個 [Algolia](https://www.algolia.com/) 驅動;而編寫自定義驅動程序很簡單,你可以自由地使用自己的搜索實現來擴展 Scout。
<a name="installation"></a>
## 安裝
首先,使用 composer 包管理器來安裝 Scout:
composer require laravel/scout
接下來,你需要將 `ScoutServiceProvider` 添加到你的配置文件 `config/app.php` 的 `providers` 數組中:
Laravel\Scout\ScoutServiceProvider::class,
注冊好 Scout 的服務提供器之后,你還需使用Artisan 命令 `vendor:publish` 生成 Scout 的配置文件。這個命令會在你的 `config` 目錄下生成 `scout.php` 配置文件:
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
最后,將 `Laravel\Scout\Searchable` trait 加到你想要搜索的模型中。這個 trait 會注冊一個模型觀察者來保持搜索驅動程序與模型的同步:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
}
<a name="queueing"></a>
### 隊列
雖然不是嚴格要求使用 Scout,但在使用這個庫之前,強烈建議你配置一個 [隊列驅動程序](/docs/{{version}}/queues)。使用隊列來對處理 Scout 將所有模型信息同步到搜索索引的操作,會極大的減少 Web 頁面的響應時間。
一旦配置了隊列驅動程序,就要在 `config/scout.php` 配置文件中設置 `queue` 的值為 `true`:
'queue' => true,
<a name="driver-prerequisites"></a>
### 驅動之前
#### Algolia
使用 Algolia 驅動時,需要在 `config/scout.php` 配置文件配置你的 Algolia `id` 和 `secret` 憑證。配置好憑證之后, 還需要使用 Composer 包管理器安裝 Algolia PHP SDK :
composer require algolia/algoliasearch-client-php
<a name="configuration"></a>
## 配置
<a name="configuring-model-indexes"></a>
### 配置模型索引
每個 Eloquent 模型與給定的搜索「索引」同步,這個「索引」包含該模型的所有可搜索記錄。換句話說,你可以把每一個「索引」設想為一張 MySQL 數據表。默認情況下,每個模型都會被持久化到與模型的「表」名(通常是模型名稱的復數形式)相匹配的索引。你也可以通過覆蓋模型上的 `searchableAs` 方法來自定義模型的索引:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* Get the index name for the model.
*
* @return string
*/
public function searchableAs()
{
return 'posts_index';
}
}
<a name="configuring-searchable-data"></a>
### 配置可搜索的數據
默認情況下,「索引」會從模型的 `toArray` 方法中讀取數據來做持久化。如果要自定義同步到搜索索引的數據,可以覆蓋模型上的 `toSearchableArray` 方法:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// Customize array...
return $array;
}
}
<a name="indexing"></a>
## 索引
<a name="batch-import"></a>
### 批量導入
如果你想要將 Scout 安裝到現有的項目中,你可能已經有了想要導入搜索驅動的數據庫記錄。使用 Scout 提供的Artisan 命令 `import` 把所有現有記錄導入到搜索索引里:
php artisan scout:import "App\Post"
<a name="adding-records"></a>
### 添加記錄
當你將 `Laravel\Scout\Searchable` trait 添加到模型中,你需要做的是 `save` 一個模型實例,它就會自動添加到你的搜索索引。如果你已經將 Scout 配置為 [使用隊列](#queueing),那這個操作會在后臺由你的隊列工作進程來執行:
$order = new App\Order;
// ...
$order->save();
#### 使用隊列添加
如果你想通過 Eloquent 查詢構造器將模型集合添加到搜索索引中,你也可以在 Eloquent 查詢構造器上鏈式調用 `searchable` 方法。`searchable` 會把構造器的查詢 [結果分塊](/docs/{{version}}/eloquent#chunking-results) 并且將記錄添加到你的搜索索引里。同樣的,如果你已經配置 Scout 為使用隊列,則所有的數據塊將在后臺由你的隊列工作進程添加:
// 使用 Eloquent 查詢構造器增加...
App\Order::where('price', '>', 100)->searchable();
// 使用模型關系增加記錄...
$user->orders()->searchable();
// 使用集合增加記錄...
$orders->searchable();
`searchable` 方法可以被看做是「更新插入」的操作。換句話說,如果模型記錄已經在你的索引里了,它就會被更新。如果搜索索引中不存在,則將其添加到索引中。
<a name="updating-records"></a>
### 更新記錄
要更新可搜索的模型,只需要更新模型實例的屬性并將模型 `save` 到數據庫。Scout 會自動將更新同步到你的搜索索引中:
$order = App\Order::find(1);
// 更新 order...
$order->save();
你也可以在 Eloquent 查詢語句上使用 `searchable` 方法來更新一個模型的集合。如果這個模型不存在你檢索的索引里,就會被創建:
// 使用 Eloquent 查詢語句更新...
App\Order::where('price', '>', 100)->searchable();
// 你也可以使用模型關系更新...
$user->orders()->searchable();
// 你也可以使用集合更新...
$orders->searchable();
<a name="removing-records"></a>
### 刪除記錄
簡單地使用 `delete` 從數據庫中刪除該模型就可以移除索引里的記錄。這種刪除形式甚至與 [軟刪除](/docs/{{version}}/eloquent#soft-deleting) 的模型兼容:
$order = App\Order::find(1);
$order->delete();
如果你不想在刪除記錄之前檢索模型,可以在 Eloquent 查詢實例或集合上使用 `unsearchable` 方法:
// 通過 Eloquent 查詢刪除...
App\Order::where('price', '>', 100)->unsearchable();
// 通過模型關系刪除...
$user->orders()->unsearchable();
// 通過集合刪除...
$orders->unsearchable();
<a name="pausing-indexing"></a>
### 暫停索引
你可能需要在執行一批 Eloquent 操作的時候,不同步模型數據到搜索索引。此時你可以使用 `withoutSyncingToSearch` 方法來執行此操作。這個方法接受一個立即執行的回調。該回調中所有的操作都不會同步到模型的索引:
App\Order::withoutSyncingToSearch(function () {
// 執行模型動作...
});
<a name="searching"></a>
## 搜索
你可以使用 `search` 方法來搜索模型。`search` 方法接受一個用于搜索模型的字符串。你還需在搜索查詢上鏈式調用 `get` 方法,才能用給定的搜索語句查詢與之匹配的 Eloquent 模型:
$orders = App\Order::search('Star Trek')->get();
Scout 搜索返回 Eloquent 模型的集合,因此你可以直接從路由或控制器返回結果,它們會被自動轉換成 JSON 格式:
use Illuminate\Http\Request;
Route::get('/search', function (Request $request) {
return App\Order::search($request->search)->get();
});
如果你想在它們返回 Eloquent 模型前得到原結果,你應該使用`raw` 方法:
$orders = App\Order::search('Star Trek')->raw();
搜索查詢通常會在模型的 [`searchableAs`](#configuring-model-indexes) 方法指定的索引上執行。當然,你也可以使用 `within` 方法指定應該搜索的自定義索引:
$orders = App\Order::search('Star Trek')
->within('tv_shows_popularity_desc')
->get();
<a name="where-clauses"></a>
### Where 語句
Scout 允許你在搜索查詢中增加簡單的「where」語句。目前,這些語句只支持基本的數值等式檢查,并且主要是用于根據擁有者的 ID 進行的范圍搜索查詢。由于搜索索引不是關系型數據庫,因此當前不支持更高級的「where」語句:
$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();
<a name="pagination"></a>
### 分頁
除了檢索模型的集合,你也可以使用 `paginate` 方法對搜索結果進行分頁。這個方法會返回一個就像 [傳統的 Eloquent 查詢分頁](/docs/{{version}}/pagination) 一樣的 `Paginator` 實例:
$orders = App\Order::search('Star Trek')->paginate();
你可以通過將數量作為第一個參數傳遞給 `paginate` 方法來指定每頁檢索多少個模型:
$orders = App\Order::search('Star Trek')->paginate(15);
獲取到檢索結果后,就可以使用 [Blade](/docs/{{version}}/blade) 來渲染分頁鏈接從而顯示結果,就像傳統的 Eloquent 查詢分頁一樣:
<div class="container">
@foreach ($orders as $order)
{{ $order->price }}
@endforeach
</div>
{{ $orders->links() }}
<a name="custom-engines"></a>
## 自定義引擎
#### 寫引擎
如果內置的 Scout 搜索引擎不能滿足你的需求,你可以寫自定義的引擎并且將它注冊到 Scout。你的引擎需要繼承 `Laravel\Scout\Engines\Engine` 抽象類,這個抽象類包含了你自定義的引擎必須要實現的五種方法:
use Laravel\Scout\Builder;
abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function map($results, $model);
在 `Laravel\Scout\Engines\AlgoliaEngine` 類里查看這些方法會對你有較大的幫助。這個類會為你在學習如何在自定義引擎中實現這些方法提供一個好的起點。
#### 注冊引擎
一旦你寫好了自定義引擎,你可以用 Scout 引擎管理的 `extend` 方法將它注冊到 Scout。你只需要從 `AppServiceProvider` 下的 `boot` 方法或者應用中使用的任何一個服務提供器調用 `extend` 方法。舉個例子,如果你寫好了一個 `MySqlSearchEngine`,你可以像這樣去注冊它:
use Laravel\Scout\EngineManager;
/**
* 引導任何應用服務。
*
* @return void
*/
public function boot()
{
resolve(EngineManager::class)->extend('mysql', function () {
return new MySqlSearchEngine;
});
}
引擎注冊后,你可以在 `config/scout.php` 配置文件中指定它為默認的 Scout `driver`:
'driver' => 'mysql',
## 譯者署名
| 用戶名 | 頭像 | 職能 | 簽名 |
| ---| --- | --- | --- |
| [@Insua](https://phphub.org/users/3853) | <img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/3853_1457586148.jpeg?imageView2/1/w/100/h/100"/> | 翻譯 | happay coding with laravel+vue |
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明