??WebmanScout 全文搜索-laravel orm專用

安裝
composer require shopwwi/webman-scout
- 如果覺(jué)得方便了你 不要吝嗇你的小星星哦 tycoonSong8988354@qq.com
- 不適用于非 laravel orm
- 此插件源于laravel/scout 感謝偉大的開(kāi)源付出
使用方法
設(shè)置
當(dāng)使用 xunsearch
時(shí),需提前在config/plugin/shopwwi/scout/ini下創(chuàng)建「indexName」.ini文件,亦可指定ini文件夾路徑
// 路徑config/plugin/shopwwi/scout
'driver' => 'meilisearch', // 支持"algolia", "meilisearch","elasticsearch", "database", "collection", "null","xunsearch"
'queue' => false, // 隊(duì)列默認(rèn)關(guān)閉 開(kāi)啟隊(duì)列請(qǐng)先安裝composer require webman/redis-queue
'xunsearch' => [
'path' => config_path().'/plugin/shopwwi/scout/ini/'
]
搜索驅(qū)動(dòng)安裝
- algolia
composer require algolia/algoliasearch-client-php
- xunsearch
composer require hightman/xunsearch
- meilisearch
composer require meilisearch/meilisearch-php
- elasticsearch
composer require elasticsearch/elasticsearch
命令行
- 創(chuàng)建index 一般無(wú)需操作 elasticsearch需要
php webman scout:index 'goods'
- 刪除index 如非model設(shè)定 一般為表名
php webman scout:delete-index 'goods'
- 初始數(shù)據(jù)model導(dǎo)入 --chunk導(dǎo)入批次數(shù)量 不宜設(shè)置過(guò)大哦
php webman scout:import 'app\model\Goods' --chunk=200
- 重置清空模型數(shù)據(jù)
php webman scout:flush 'app\model\Goods'
配置模型索引
每個(gè) Eloquent 模型都與給定的搜索 「索引」同步,該索引包含該模型的所有可搜索記錄。 換句話說(shuō),你可以將每個(gè)索引視為一個(gè) MySQL 表。 默認(rèn)情況下,每個(gè)模型都將持久化到與模型的典型 「表」名稱匹配的索引。 通常,是模型名稱的復(fù)數(shù)形式; 但你可以通過(guò)重寫(xiě)模型上的 searchableAs
方法來(lái)自由地自定義模型的索引:
<?php
namespace app\model;
use Illuminate\Database\Eloquent\Model;
use Shopwwi\WebmanScout\Searchable;
class Goods extends Model
{
use Searchable;
/**
* 與模型關(guān)聯(lián)的表名 后綴不帶s的必須設(shè)置 默認(rèn)是帶s的
*
* @var string
*/
protected $table = 'goods';
/**
* 獲取與模型關(guān)聯(lián)的索引的名稱。
* 如果不存在該類(lèi) 則默認(rèn)為表名
* @return string
*/
public function searchableAs()
{
return 'posts_index';
}
}
配置可搜索數(shù)據(jù)
默認(rèn)情況下,模型以完整的 toArray
格式持久化到搜索索引。如果要自定義同步到搜索索引的數(shù)據(jù),可以覆蓋模型上的 toSearchableArray
方法:
<?php
namespace app\model;
use Illuminate\Database\Eloquent\Model;
use Shopwwi\WebmanScout\Searchable;
class Goods extends Model
{
use Searchable;
/**
* 獲取模型的可索引的數(shù)據(jù)。
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// 自定義數(shù)據(jù)數(shù)組...
return $array;
}
}
配置模型 ID
默認(rèn)情況下,Scout 將使用模型的主鍵作為搜索索引中存儲(chǔ)的唯一 ID /key。 可以通過(guò)模型上的 getScoutKey
和 getScoutKeyName
方法自定義:
<?php
namespace app\model;
use Illuminate\Database\Eloquent\Model;
use Shopwwi\WebmanScout\Searchable;
class Goods extends Model
{
use Searchable;
/**
* 獲取用于索引模型的值
*
* @return mixed
*/
public function getScoutKey()
{
return $this->email;
}
/**
* 獲取用于索引模型的鍵名
*
* @return mixed
*/
public function getScoutKeyName()
{
return 'email';
}
}
自定義數(shù)據(jù)庫(kù)搜索策略
默認(rèn)情況下,數(shù)據(jù)庫(kù)引擎將對(duì)你已配置為可搜索 的每個(gè)模型屬性執(zhí)行「where like」查詢。但是,在某些情況下,這可能會(huì)導(dǎo)致性能不佳。因此,你可以通過(guò)配置數(shù)據(jù)庫(kù)引擎的搜索策略,使某些指定的列使用全文搜索查詢或僅使「where like」約束來(lái)搜索字符串的前綴(example%),而不是在整個(gè)字符串中搜索(%example%)。
要定義此行為,你可以將 PHP 屬性分配給模型的 toSearchableArray
方法。任何未分配額外搜索策略行為的列將繼續(xù)使用默認(rèn)的「where like」策略:
<?php
namespace app\model;
use Illuminate\Database\Eloquent\Model;
use Shopwwi\WebmanScout\Searchable;
class Goods extends Model
{
use Searchable;
use Shopwwi\WebmanScout\Attributes\SearchUsingFullText;
use Shopwwi\WebmanScout\Attributes\SearchUsingPrefix;
/**
* 獲取模型的可索引數(shù)據(jù)數(shù)組。
*
* @return array
*/
#[SearchUsingPrefix(['id', 'email'])]
#[SearchUsingFullText(['bio'])]
public function toSearchableArray()
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'bio' => $this->bio,
];
}
}
修改導(dǎo)入查詢
如果要修改用于檢索所有模型以進(jìn)行批量導(dǎo)入的查詢,可以在模型上定義 makeAllSearchableUsing
方法。這是一個(gè)很好的地方,可以在導(dǎo)入模型之前添加任何可能需要的即時(shí)關(guān)系加載:
<?php
namespace app\model;
use Illuminate\Database\Eloquent\Model;
use Shopwwi\WebmanScout\Searchable;
class Goods extends Model
{
use Searchable;
/**
* 在使所有模型都可搜索時(shí),修改用于檢索模型的查詢。
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function makeAllSearchableUsing($query)
{
return $query->with('author');
}
}
添加記錄
一旦將 Shopwwi\WebmanScout\Searchable
trait 添加到模型中,你只需 save 或 create 模型實(shí)例,它就會(huì)自動(dòng)添加到搜索索引中。如果已將 Scout 配置為 使用隊(duì)列,此操作將由隊(duì)列 worker 進(jìn)程在后臺(tái)執(zhí)行:
use app\model\Goods;
$goods = new Goods;
// ...
$goods->save();
通過(guò)查詢添加
如果你希望通過(guò) Eloquent 查詢將模型集合添加到搜索索引中,你也可以在 Eloquent 查詢構(gòu)造器上鏈?zhǔn)秸{(diào)用 searchable
方法。searchable
會(huì)把構(gòu)造器的查詢 結(jié)果分塊 并將記錄添加到搜索索引中。同樣,如果你已將 Scout 配置為使用隊(duì)列,則隊(duì)列 worker 將在后臺(tái)導(dǎo)入所有塊:
use app\model\Goods;
Goods::where('price', '>', 100)->searchable();
你還可以在 Eloquent 關(guān)聯(lián)實(shí)例上調(diào)用 searchable
方法:
$goods->images()->searchable();
或者,如果內(nèi)存中已經(jīng)有一組 Eloquent 模型,可以調(diào)用集合實(shí)例上的 searchable
方法,將模型實(shí)例添加到相應(yīng)的索引中:
$goods->searchable();
更新記錄
要更新可搜索的模型,只需要更新模型實(shí)例的屬性并將模型 save
到數(shù)據(jù)庫(kù)。Scout 會(huì)自動(dòng)將更新同步到你的搜索索引中:
use app\model\Goods;
$goods = Goods::find(1);
// 更新商品...
$goods->save();
你也可以在 Eloquent 查詢語(yǔ)句上使用 searchable
方法來(lái)更新一個(gè)模型的集合。如果這個(gè)模型不存在你檢索的索引里,就會(huì)被創(chuàng)建:
Order::where('price', '>', 100)->searchable();
如果要更新關(guān)系中所有模型的搜索索引記錄,可以在關(guān)系實(shí)例上調(diào)用 searchable
:
$user->orders()->searchable();
或者,如果內(nèi)存中已經(jīng)有 Eloquent 模型集合,則可以調(diào)用集合實(shí)例上的 searchable
方法來(lái)更新相應(yīng)索引中的模型實(shí)例:
$orders->searchable();
移除記錄
要從索引中刪除記錄,只需從數(shù)據(jù)庫(kù)中 delete
模型即可。即使你正在使用 軟刪除 模型,也可以這樣做:
use app\model\Goods;
$goods = Goods::find(1);
// 更新商品...
$goods->delete();
如果你不希望記錄在刪除之前被檢索到,可以在 Eloquent 查詢實(shí)例或集合上使用 unsearchable
方法:
Order::where('price', '>', 100)->unsearchable();
如果要?jiǎng)h除關(guān)系中所有模型的搜索索引記錄,可以在關(guān)系實(shí)例上調(diào)用 unsearchable
:
$user->orders()->unsearchable();
或者,如果內(nèi)存中已經(jīng)有 Eloquent 模型集合,則可以調(diào)用集合實(shí)例上的 unsearchable
方法,從相應(yīng)的索引中刪除模型實(shí)例:
$orders->unsearchable();
暫停索引
你可能需要在執(zhí)行一批 Eloquent 操作的時(shí)候,不同步模型數(shù)據(jù)到搜索索引。此時(shí)你可以使用 withoutSyncingToSearch
方法來(lái)執(zhí)行此操作。這個(gè)方法接受一個(gè)立即執(zhí)行的回調(diào)。該回調(diào)中所有的操作都不會(huì)同步到模型的索引:
use app\model\Goods;
Goods::::withoutSyncingToSearch(function () {
// 執(zhí)行模型操作...
});
有條件的搜索模型實(shí)例
有時(shí)你可能只需要在某些條件下使模型可搜索。例如,假設(shè)你有 app\model\Goods
模型可能是兩種狀態(tài)之一:「?jìng)}庫(kù)中」和「線上」。你可能只允許搜索 「線上」的商品。為了實(shí)現(xiàn)這一點(diǎn),你需要在模型中定義一個(gè) shouldBeSearchable
方法:
/**
* 確定模型是否可搜索
*
* @return bool
*/
public function shouldBeSearchable()
{
return $this->isOnline();
}
搜索
你可以使用 search
方法來(lái)搜索模型。search
方法接受一個(gè)用于搜索模型的字符串。你還需要在搜索查詢上鏈?zhǔn)秸{(diào)用 get
方法,才能用給定的搜索語(yǔ)句查詢與之匹配的 Eloquent 模型:
use app\model\Goods;
$goods = Goods::search('webman')->get();
由于 Scout 搜索返回 Eloquent 模型的集合,你甚至可以直接從路由或控制器返回結(jié)果,結(jié)果將自動(dòng)轉(zhuǎn)換為 JSON :
use app\model\Goods;
use support\Request;
Route::get('/search', function (Request $request) {
return Goods::search($request->search)->get();
});
如果你想在它們轉(zhuǎn)換成 Eloquent 模型前得到原始結(jié)果,你應(yīng)該使用 raw 方法:
$goods = Goods::search('webman')->raw();
自定義索引
搜索查詢通常會(huì)在模型的 searchableAs
方法指定的索引上執(zhí)行。但是,你可以使用 within
方法指定應(yīng)搜索的自定義索引:
$goods = Goods::search('webman')
->within('goods_desc')
->get();
Where 子句
Scout 允許你在搜索查詢中添加簡(jiǎn)單的「where」子句。目前,這些子句僅支持基本的數(shù)值相等性檢查,主要用于按所有者 ID 確定搜索查詢的范圍。
use app\model\Goods;
$goods = Goods::search('webman')->where('status', 1)->get();
//你可以使用 whereIn 方法將結(jié)果限制在給定的一組值上:
$goods = Goods::search('webman')->whereIn(
'status', ['paid', 'open']
)->get();
由于搜索索引不是關(guān)系數(shù)據(jù)庫(kù),因此目前不支持更高級(jí)的「where」子句。
分頁(yè)
除了檢索模型的集合,你也可以使用 paginate 方法對(duì)搜索結(jié)果進(jìn)行分頁(yè)。默認(rèn)傳參為「page」「limit」
use app\model\Goods;
$goods = Goods::search('webman')->paginate();
通過(guò)將數(shù)量作為第一個(gè)參數(shù)傳遞給 paginate 方法,可以指定每頁(yè)要檢索多少個(gè)模型:
$goods = Goods::search('webman')->paginate(15);
// 亦可指定參數(shù)
$goods = Goods::search('webman')->paginate(request()->input('page',1),'page',request()->input('limit',10));
軟刪除
如果你索引的模型是 軟刪除,并且你需要搜索已刪除的模型,請(qǐng)將 config 配置文件中的 soft_delete 選項(xiàng)設(shè)置為 true:
'soft_delete' => true,
當(dāng)此配置選項(xiàng)為 true 時(shí),Scout 不會(huì)從搜索索引中刪除軟刪除的模型。相反,它將在索引記錄上設(shè)置一個(gè)隱藏的__soft_deleted 屬性。然后,你可以在搜索時(shí)使用 withTrashed 或 onlyTrashed 方法檢索軟刪除記錄:
use app\model\Goods;
// 檢索結(jié)果包括已刪除記錄
$goods = Goods::search('webman')->withTrashed()->get();
// 僅檢索已刪除記錄...
$goods = Goods::search('webman')->onlyTrashed()->get();