* * * * *
[TOC]
## 簡介
Laravel Scout 是針對?[Eloquent 模型](https://laravel-china.org/docs/laravel/5.4/eloquent)?開發的一個簡單的,基于驅動的全文檢索系統。Scout 使用模型觀察者時會自動保持你的檢索索引與你的 Eloquent 記錄同步。
目前,Scout 帶著一個?[Algolia](https://www.algolia.com/)?驅動;然而,擴展 Scout 并不難,你可以通過自定義驅動來自由的擴展 Scout。
## 安裝
首先,使用 composer 包管理器來安裝 Scout:
~~~
composer require laravel/scout
~~~
接下來,你需要將?`ScoutServiceProvider`?添加到你的?`config/app.php`?配置文件的?`providers`?數組中:
~~~
Laravel\Scout\ScoutServiceProvider::class,
~~~
注冊好 Scout 的服務提供者之后,你可以使用?`vendor:publish`?Artisan 命令生成 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;
}
~~~
### 隊列
雖然 Scout 沒有限制你必須使用隊列,但是建議你為 Scout 配置一個?[隊列驅動](https://laravel-china.org/docs/laravel/5.4/queues)。使用隊列來對處理 Scout 對數據模型的索引,將會極大的提高你的頁面響應時間。
一旦你配置了隊列驅動,在你的?`config/scout.php`?配置文件中設置?`queue`?的值為?`true`:
~~~
'queue' => true,
~~~
### 驅動必要設置
#### Algolia
當你使用 Algolia 驅動時,你需要在你的?`config/scout.php`?配置文件配置你的 Algolia?`id`?和?`secret`?認證資料。配置好認證資料以后, 你還需要使用 composer 包管理器安裝 Algolia PHP SDK :
~~~
composer require algolia/algoliasearch-client-php
~~~
## 配置
### 配置模型索引
每一個 Eloquent 模型都會同步到對應的一個檢索「索引」中,「索引」里包含了此模型的所有可檢索的記錄。你可以把每一個「索引」設想為一張 MySQL 數據表。默認情況下,「索引」的名稱與模型對應數據表名稱一致,也就是說,是模型名稱的復數形式。當然,你也可以在模型類使用?`searchableAs`?方法來重寫「索引」名稱:
~~~
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* 得到該模型索引的名稱。
*
* @return string
*/
public function searchableAs()
{
return 'posts_index';
}
}
~~~
### 配置可檢索的數據
默認情況下,「索引」會從模型的?`toArray`?方法中讀取數據來做數據持久化。你也可以通過重寫?`toSearchableArray`?方法來自定義數據到「索引」的同步:
~~~
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* 得到該模型可索引數據的數組。
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// 自定義數組數據...
return $array;
}
}
~~~
## 索引
### 批量導入
如果你想要將 Scout 安裝到已經存在的項目里,那你也需要將已經在數據庫里的數據導入到搜索引擎里。你可以使用 Scout 提供的?`import`?Artisan 命令把現有的模型數據導入到「索引」里:
~~~
php artisan scout:import "App\Post"
~~~
### 添加記錄
當你將?`Laravel\Scout\Searchable`?添加到模型之后,你只需要?`save`?一個模型實例,它就會自動的添加到你檢索的索引里。如果你的 Scout 配置里?[使用隊列](https://laravel-china.org/docs/laravel/5.4/scout/1276#queueing)?這個操作會在后臺由你的 queue worker 執行:
~~~
$order = new App\Order;
// ...
$order->save();
~~~
#### 使用隊列添加
如果你想使用 Eloquent 構造器添加模型的集合到你的檢索索引里,你也可以在 Eloquent 構造器上鏈式調用?`searchable`?方法。`searchable`?會把構造器的查詢?[結果分塊](https://laravel-china.org/docs/laravel/5.4/eloquent#chunking-results)?并且將記錄添加到你的檢索索引里。同樣的,如果你配置 Scout 使用隊列,所有的數據塊將會在后臺由你的 queue workers 添加:
~~~
// 使用 Eloquent 查詢語句增加...
App\Order::where('price', '>', 100)->searchable();
// 你也可以使用模型關系增加記錄...
$user->orders()->searchable();
// 你也可以使用集合增加記錄...
$orders->searchable();
~~~
`searchable`?方法可以被看做是「增量更新」的操作。換句話說,如果一個模型的記錄已經在你的索引里了,它就會被更新,如果不在,就會被插入。
### 更新記錄
你只需要更新一個模型實例的屬性并且?`save`?這個模型到你的數據庫里,就更新了這個可檢索的模型。Scout 會自動更新這個變化到你的檢索索引里:
~~~
$order = App\Order::find(1);
// 更新 order...
$order->save();
~~~
你也可以在 Eloquent 查詢語句上使用?`searchable`?方法來更新一個模型的集合。如果這個模型不存在你檢索的索引里,就會被創建:
~~~
// 使用 Eloquent 查詢語句更新...
App\Order::where('price', '>', 100)->searchable();
// 你也可以使用模型關系更新...
$user->orders()->searchable();
// 你也可以使用集合更新...
$orders->searchable();
~~~
### 刪除記錄
簡單的使用?`delete`?從數據庫刪除模型就可以移除索引里的記錄。這種移除的方式也兼容?[軟刪除](https://laravel-china.org/docs/laravel/5.4/eloquent#soft-deleting)?模型:
~~~
$order = App\Order::find(1);
$order->delete();
~~~
或者說是你不想在刪除記錄之前檢索模型,你也可以在 Eloquent 查詢語句的實例或集合上使用?`unsearchable`?方法:
~~~
// 使用 Eloquent 查詢語句移除索引...
App\Order::where('price', '>', 100)->unsearchable();
// 你也可以使用模型關系移除索引...
$user->orders()->unsearchable();
// 你也可以使用集合移除索引...
$orders->unsearchable();
~~~
### 暫停索引
當你想要對 Eloquent 模型完成一系列的操作并且不想將它們的數據同步到檢索的索引里時,你也可以使用?`withoutSyncingToSearch`?方法。這個方法接受一個立即執行的回調函數。函數內部所有的操作都不會被同步到模型的索引里:
~~~
App\Order::withoutSyncingToSearch(function () {
// Perform model actions...
});
~~~
## 檢索
你可以對一個模型使用 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();
});
~~~
### Where 語句
Scout 允許你增加一個簡單的「where」語句鏈接到搜索語句上。目前,這些語句只支持簡單的數字相等檢查,并且主要用來查詢范圍內的擁有者的 ID。由于檢索索引是非關系型數據庫,更高級的「where」暫時不支持:
~~~
$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();
~~~
### 分頁
除了檢索模型的集合,你也可以使用?`paginate`?方法對檢索結果進行分頁。這個方法會返回一個 Paginator 實例就像你?[對傳統的 Eloquent 查詢語句進行分頁](https://laravel-china.org/docs/laravel/5.4/pagination)?:
~~~
$orders = App\Order::search('Star Trek')->paginate();
~~~
你可以通過通過?`paginate`?方法的第一個參數來指定檢索的結果每頁要顯示的數量:
~~~
$orders = App\Order::search('Star Trek')->paginate(15);
~~~
一旦你獲取到結果,就可以對結果進行顯示,就像你對傳統的 Eloquent 查詢語句進行分頁一樣,使用?[Blade](https://laravel-china.org/docs/laravel/5.4/blade)?來渲染頁面的鏈接:
~~~
<div class="container">
@foreach ($orders as $order)
{{ $order->price }}
@endforeach
</div>
{{ $orders->links() }}
~~~
## 自定義引擎
#### 寫一個引擎
如果 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;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
resolve(EngineManager::class)->extend('mysql', function () {
return new MySqlSearchEngine;
});
}
~~~
一旦你的引擎注冊好了,你可以在?`config/scout.php`?配置文件中指定它為默認的 Scout?`driver`:
~~~
'driver' => 'mysql',
~~~
- 前言
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- 請求周期
- 開發環境部署
- Homestead
- Valet
- 核心概念
- 服務容器
- 服務提供者
- Facades
- Contracts
- HTTP層
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- Session
- 表單驗證
- 前端
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- Passport OAuth 認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 錯誤與日志
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Scout 全文搜索
- Socialite 社會化登錄