[ Laravel 5.4 文檔 ] 官方包 —— Laravel Scout

1醉拓、簡(jiǎn)介

Laravel ScoutEloquent 模型全文搜索實(shí)現(xiàn)提供了簡(jiǎn)單的擂仍、基于驅(qū)動(dòng)的解決方案,通過(guò)使用模型觀察者粟焊,Scout 會(huì)自動(dòng)同步更新模型記錄的索引
目前孙蒙,Scout 通過(guò) Algolia 驅(qū)動(dòng)提供搜索功能项棠,不過(guò),編寫(xiě)自定義驅(qū)動(dòng)很簡(jiǎn)單挎峦,你可以很輕松地通過(guò)自己的搜索實(shí)現(xiàn)來(lái)擴(kuò)展 Scout香追。

2、安裝

首先坦胶,我們通過(guò) Composer 包管理器來(lái)安裝 Scout:

composer require laravel/scout

接下來(lái)透典,需要添加 ScoutServiceProvider到配置文件 config/app.phpproviders 數(shù)組:

Laravel\Scout\ScoutServiceProvider::class,

注冊(cè) Scout 服務(wù)提供者之后,還需要通過(guò) Artisan 命令 vendor:publish發(fā)布Scout 配置顿苇,該命令會(huì)發(fā)布配置文件 scout.phpconfig目錄:

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

最后掷匠,如果你想要模型變得可搜索,需要添加 Laravel\Scout\Searchable trait 到模型類岖圈,該 trait 會(huì)注冊(cè)模型觀察者來(lái)保持搜索驅(qū)動(dòng)與模型記錄數(shù)據(jù)的一致性:

<?php namespace App;
    use Laravel\Scout\Searchable;
    use Illuminate\Database\[Eloquent](https://laravelacademy.org/tags/eloquent)\Model;
    class Post extends Model{ 
        use Searchable;
    }

隊(duì)列

盡管不強(qiáng)制使用 Scout讹语,不過(guò)在使用這個(gè)庫(kù)之前強(qiáng)烈建議考慮配置一個(gè)隊(duì)列驅(qū)動(dòng)。運(yùn)行一個(gè)隊(duì)列進(jìn)程將允許 Scout 把所有同步模型信息到搜索索引的操作推送到隊(duì)列中蜂科,從而為應(yīng)用的 web 界面提供更快的響應(yīng)時(shí)間顽决。
配置好隊(duì)列驅(qū)動(dòng)后,在配置文件 config/scout.php中設(shè)置 queue選項(xiàng)的值為true

'queue' => true,

驅(qū)動(dòng)預(yù)備知識(shí)

Algolia
使用 Algolia 驅(qū)動(dòng)的話导匣,需要在配置文件 config/scout.php中設(shè)置 Algolia 的 idsecret信息才菠。配置好之后,還需要通過(guò) Composer 包管理器安裝 Algolia PHP SDK:

composer require algolia/algoliasearch-client-php

3贡定、配置

配置模型索引

每個(gè) Eloquent 模型都是通過(guò)給定的搜索“索引”進(jìn)行同步赋访,該索引包含了所有可搜索的模型記錄,換句話說(shuō),你可以將索引看作是一個(gè) MySQL 數(shù)據(jù)表蚓耽。默認(rèn)情況下渠牲,每個(gè)模型都會(huì)被持久化到與模型對(duì)應(yīng)表名(通常是模型名稱的復(fù)數(shù)形式)相匹配的索引中,不過(guò)步悠,你可以通過(guò)重寫(xiě)模型中的 searchableAs 方法來(lái)覆蓋這一默認(rèn)設(shè)置:

<?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'; 
          }
      }

配置搜索數(shù)據(jù)

默認(rèn)情況下签杈,模型以完整的 toArray格式持久化到搜索索引,如果你想要自定義被持久化到搜索索引的數(shù)據(jù)鼎兽,可以重寫(xiě)模型上的 toSearchableArray方法:

<?php namespace App;
      use Laravel\Scout\Searchable;
      use Illuminate\Database\Eloquent\Model;
      class Post extends Model{ 
          use Searchable; 
          /** 
            * 獲取模型的索引數(shù)據(jù)數(shù)組 
            * 
            * @return array 
            */ 
            public function toSearchableArray() { 
                 $array = $this->toArray(); // 自定義數(shù)組... 
                 return $array; 
            }
      }

4答姥、索引

批量導(dǎo)入

如果你想要安裝 Scout 到已存在的項(xiàng)目,你可能已經(jīng)有了想要導(dǎo)入搜索驅(qū)動(dòng)的數(shù)據(jù)庫(kù)記錄谚咬,Scout 提供了 Artisan 命令 import用于導(dǎo)入所有已存在的數(shù)據(jù)到搜索索引:

php artisan scout:import "App\Post"

添加記錄

添加 Laravel\Scout\Searchable trait 到模型之后鹦付,剩下需要做的就是保存模型實(shí)例,然后該實(shí)例會(huì)自動(dòng)被添加到模型索引择卦,如果你配置了 Scout 使用隊(duì)列敲长,該操作會(huì)被推送到隊(duì)列在后臺(tái)執(zhí)行:

$order = new App\Order;
// ...
$order->save();

通過(guò)查詢添加
如果你想要通過(guò) Eloquent 查詢添加模型集合到搜索索引,可以在 Eloquent 查詢之后追加 searchable方法調(diào)用互捌。searchable方法會(huì)分組塊進(jìn)行查詢并將結(jié)果添加到搜索索引潘明。再次強(qiáng)調(diào),如果你配置了 Scout 使用隊(duì)列秕噪,所有的組塊查詢會(huì)被推送到隊(duì)列在后臺(tái)進(jìn)行:

// 通過(guò)Eloquent查詢添加...
App\Order::where('price', '>', 100)->searchable();

// 還可以通過(guò)關(guān)聯(lián)關(guān)系添加記錄...
$user->orders()->searchable();

// 還可以通過(guò)集合添加記錄...
$orders->searchable();

searchable方法還可以進(jìn)行“upsert”操作钳降,換句話說(shuō),如果模型記錄已經(jīng)存在于索引腌巾,則會(huì)被更新遂填,如果不存在,則會(huì)被添加澈蝙。

更新記錄

要更新可搜索的模型吓坚,需要更新模型實(shí)例的屬性并保存模型到數(shù)據(jù)庫(kù)。Scout 會(huì)自動(dòng)持久化更新到搜索索引:

$order = App\Order::find(1);
// 更新訂單...
$order->save();

還可以使用模型查詢提供的 searchable方法更新模型集合灯荧,如果模型在搜索索引中不存在礁击,則會(huì)被創(chuàng)建:

// 通過(guò)Eloquent查詢更新...
App\Order::where('price', '>', 100)->searchable();
// 還可以通過(guò)關(guān)聯(lián)關(guān)系更新...
$user->orders()->searchable();
// 還可以通過(guò)集合更新...
$orders->searchable();

移除記錄

要從索引中移除記錄,只需從數(shù)據(jù)庫(kù)中刪除記錄即可逗载,這種移除方式甚至兼容軟刪除模型:

$order = App\Order::find(1);$order->delete();

如果你在刪除記錄前不想獲取模型哆窿,可以使用模型查詢實(shí)例或集合上的 unsearchable
方法:

// 通過(guò)Eloquent查詢移除...
App\Order::where('price', '>', 100)->unsearchable();
// 還可以通過(guò)關(guān)聯(lián)關(guān)系移除...
$user->orders()->unsearchable();
// 還可以通過(guò)集合移除...
$orders->unsearchable();

暫停索引

有時(shí)候你需要在不同步模型數(shù)據(jù)到搜索索引的情況下執(zhí)行批量的 Eloquent 操作,可以通過(guò)withoutSyncingToSearch方法來(lái)實(shí)現(xiàn)厉斟。該方法接收一個(gè)立即被執(zhí)行的回調(diào)挚躯,該回調(diào)中出現(xiàn)的所有模型操作都不會(huì)同步到搜索索引:

App\Order::withoutSyncingToSearch(function () { 
// Perform model actions...
});

5、搜索

你可以通過(guò) search方法來(lái)搜索一個(gè)模型擦秽,該方法接收一個(gè)用于搜索模型的字符串码荔,然后你還需要在這個(gè)搜索查詢上調(diào)用一個(gè) get方法來(lái)獲取與給定搜索查詢相匹配的 Eloquent 模型:

$orders = App\Order::search('Star Trek')->get();

由于 Scout 搜索返回的是 Eloquent 模型集合漩勤,你甚至可以直接從路由或控制器中返回結(jié)果,它們將會(huì)被自動(dòng)轉(zhuǎn)換為 JSON 格式:

use Illuminate\Http\Request;

Route::get('/search', function (Request $request) { 
    return App\Order::search($request->search)->get();
});

where子句
Scout 允許你添加簡(jiǎn)單的 where 子句到搜索查詢缩搅,目前越败,這些子句僅支持簡(jiǎn)單的數(shù)值相等檢查,由于搜索索引不是關(guān)系型數(shù)據(jù)庫(kù)誉己,更多高級(jí)的 where 子句暫不支持:

$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();

分頁(yè)
除了獲取模型集合之外眉尸,還可以使用 paginate 方法對(duì)搜索結(jié)果進(jìn)行分頁(yè)域蜗,該方法返回一個(gè)Paginator實(shí)例 —— 就像你對(duì)傳統(tǒng) Eloquent 查詢進(jìn)行分頁(yè)一樣:

$orders = App\Order::search('Star Trek')->paginate();

你可以通過(guò)傳入數(shù)量作為paginate方法的第一個(gè)參數(shù)來(lái)指定每頁(yè)顯示多少個(gè)模型:

$orders = App\Order::search('Star Trek')->paginate(15);

獲取結(jié)果之后巨双,可以使用 Blade 顯示結(jié)果并渲染分頁(yè)鏈接,就像對(duì)傳統(tǒng) Eloquent 查詢進(jìn)行分頁(yè)時(shí)一樣:

<div class="container"> 
    @foreach ($orders as $order) 
        {{ $order->price }} 
    @endforeach

</div>{{ $orders->links() }}

6霉祸、自定義引擎

編寫(xiě)引擎
如果某個(gè)內(nèi)置的 Scout 搜索引擎不滿足你的需求筑累,可以編寫(xiě)自定義的引擎并將其注冊(cè)到 Scout,自定義的引擎需要繼承自抽象類 Laravel\Scout\Engines\Engine丝蹭,該抽象類包含了5個(gè)自定義引擎必須實(shí)現(xiàn)的方法:

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);

這5個(gè)方法的實(shí)現(xiàn)可以參考Laravel\Scout\Engines\AlgoliaEngine類慢宗,這個(gè)類為我們學(xué)習(xí)如何在自定義引擎中實(shí)現(xiàn)這些方法提供了最佳范本。
注冊(cè)引擎
編寫(xiě)好自定義引擎之后奔穿,可以通過(guò) Scout 引擎管理器提供的 extend方法將其注冊(cè)到Scout镜沽。你需要在 AppServiceProvider(或者其他服務(wù)提供者)的boot方法中調(diào)用這個(gè) extend方法。例如贱田,如果你編寫(xiě)了 MySqlSearchEngine缅茉,可以這樣注冊(cè):

use Laravel\Scout\EngineManager;
/** 
* 啟動(dòng)任意應(yīng)用服務(wù). 
* 
* @return void 
*/
public function boot(){ 
    resolve(EngineManager::class)->extend('mysql', function () { 
        return new MySqlSearchEngine; 
    });
}

引擎被注冊(cè)之后,可以在配置文件 config/scout.php中將其設(shè)置為 Scout 默認(rèn)的驅(qū)動(dòng):

'driver' => 'mysql',
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末男摧,一起剝皮案震驚了整個(gè)濱河市蔬墩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耗拓,老刑警劉巖拇颅,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異乔询,居然都是意外死亡樟插,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)竿刁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)黄锤,“玉大人,你說(shuō)我怎么就攤上這事们妥〔掳纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵监婶,是天一觀的道長(zhǎng)旅赢。 經(jīng)常有香客問(wèn)我齿桃,道長(zhǎng),這世上最難降的妖魔是什么煮盼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任短纵,我火速辦了婚禮,結(jié)果婚禮上僵控,老公的妹妹穿的比我還像新娘香到。我一直安慰自己,他們只是感情好报破,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布悠就。 她就那樣靜靜地躺著,像睡著了一般充易。 火紅的嫁衣襯著肌膚如雪梗脾。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天盹靴,我揣著相機(jī)與錄音炸茧,去河邊找鬼。 笑死稿静,一個(gè)胖子當(dāng)著我的面吹牛梭冠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播改备,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼控漠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了绍妨?” 一聲冷哼從身側(cè)響起润脸,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎他去,沒(méi)想到半個(gè)月后毙驯,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灾测,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年爆价,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媳搪。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铭段,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秦爆,到底是詐尸還是另有隱情序愚,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布等限,位于F島的核電站爸吮,受9級(jí)特大地震影響芬膝,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜形娇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一锰霜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桐早,春花似錦癣缅、人聲如沸哄酝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)炫七。三九已至爬立,卻和暖如春钾唬,著一層夾襖步出監(jiān)牢的瞬間万哪,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工抡秆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奕巍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓儒士,卻偏偏與公主長(zhǎng)得像的止,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子着撩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容