前言
whereof/think-scout 依据 thinkphp 设计思维参考 laravel/scout 进行扩大
whereof/think-scout 为模型的全文搜寻提供了一个简略的、基于驱动程序的解决方案。
目前,Scout 自带了一个 Elasticsearch 驱动;而编写自定义驱动程序很简略,你能够自在地应用本人的搜寻实现来扩大 Scout。
装置
composer require whereof/think-scout
命令行应用
// 创立模型索引
php think scout:index "app\\model\\User"
// 删除模型的索引
php think scout:delete-index "app\\model\\User"
// 分批将模型中的数据同步到引擎中
php think scout:import "app\\model\\User"
// 清空引擎中的数据(危险操作谨慎应用)php think scout:flush "app\\model\\User"
Scout 事件
事件 | 形容 | 案例 |
---|---|---|
onScoutUpdated | 注册模型新增 / 更新事件 | Event::trigger(‘onScoutUpdated’, new User()); |
onScoutDeleted | 注册模型删除事件 | Event::trigger(‘onScoutDeleted’, User::find(1)); |
onScoutImported | 注册模型全量新增 / 更新 | Event::trigger(‘onScoutImported’, User::find(1)); |
onScoutFlushed | 注册模型全量删除数据 | Event::trigger(‘onScoutFlushed’, new User()); |
onScoutCreateIndex | 注册模型索引创立 | Event::trigger(‘onScoutCreateIndex’, new User()); |
onScoutDeleteIndex | 注册模型索引删除 | Event::trigger(‘onScoutDeleteIndex’, new User()); |
模型事件
官网参考地址:https://www.kancloud.cn/manua…
事件 | 形容 | 事件办法名 |
---|---|---|
after_read | 查问后 | onAfterRead |
before_insert | 新增前 | onBeforeInsert |
after_insert | 新增后 | onAfterInsert |
before_update | 更新前 | onBeforeUpdate |
after_update | 更新后 | onAfterUpdate |
before_write | 写入前 | onBeforeWrite |
after_write | 写入后 | onAfterWrite |
before_delete | 删除前 | onBeforeDelete |
after_delete | 删除后 | onAfterDelete |
before_restore | 复原前 | onBeforeRestore |
after_restore | 复原后 | onAfterRestore |
手动注册 Scout 事件到模型事件中
如果须要通过模型事件来主动实现 Scout 数据增量同步到引擎中须要进行手动注册
重要事件说三遍:
手动注册 Scout 事件到模型事件中!
手动注册 Scout 事件到模型事件中!
手动注册 Scout 事件到模型事件中!
案例
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use whereof\think\scout\Searchable;
use think\facade\Event;
/**
* @mixin \think\Model
*/
class User extends Model
{
use Searchable;
public static function onAfterDelete(Model $model)
{Event::trigger('onScoutDeleted', $model);
}
public static function onAfterWrite(Model $model)
{Event::trigger('onScoutUpdated', $model);
}
}
装置
引入组件包和 Elasticsearch 驱动
composer require whereof/think-scout
// 依据本人的 elasticsearch 版本进行装置
composer require elasticsearch/elasticsearch
最初,在你要做搜寻的模型中增加 whereof\think\scout\Searchable
trait。这个 trait 会注册一个模型观察者来放弃模型和所有驱动的同步:
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use whereof\think\scout\Searchable;
/**
* @mixin \think\Model
*/
class User extends Model
{use Searchable;}
配置文件 config/scout.php
<?php
return [
/**
* Default Search Engine
* Supported: "collection", "null" "elastic"
*/
'default' => env('SCOUT_DRIVER', 'collection'),
//Soft Deletes
'soft_delete' => false,
// 分块解决数据
'chunk' => 20,
//engine Configuration
'engine' => [
'collection' => ['driver' => \whereof\think\scout\Engines\CollectionEngine::class,],
'null' => ['driver' => \whereof\think\scout\Engines\NullEngine::class,],
'elastic' => [
'driver' => \whereof\think\scout\Engines\ElasticEngine::class,
'prefix' => '',
//https://www.elastic.co/guide/cn/elasticsearch/php/current/_configuration.html
'hosts' => [
[
'host' => 'localhost',
'port' => "9200",
'scheme' => null,
'user' => null,
'pass' => null,
],
],
]
],
];
配置模型索引
每个模型与给定的搜寻「索引」同步,这个「索引」蕴含该模型的所有可搜寻记录。换句话说,你能够把每一个「索引」构想为一张 MySQL 数据表。默认状况下,每个模型都会被长久化到与模型的「表」名(通常是模型名称的复数模式)相匹配的索引。你也能够通过笼罩模型上的 searchableAs 办法来自定义模型的索引:
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use whereof\think\scout\Searchable;
/**
* @mixin \think\Model
*/
class User extends Model
{
use Searchable;
/**
* Get the index name for the model.
*
* @return string
*/
public function searchableAs()
{return $this->getTable();
}
}
暂停索引
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use whereof\think\scout\Searchable;
/**
* @mixin \think\Model
*/
class User extends Model
{
use Searchable;
/**
* Determine if the model should be searchable.
*
* @return bool
*/
public function shouldBeSearchable()
{return true;}
}
搜寻
你能够应用 search 办法来搜寻模型。search 办法承受一个用于搜寻模型的字符串。你还需在搜寻查问上链式调用 get 办法,能力用给定的搜寻语句查问与之匹配的模型模型:
User::search()->get();
如果你想在它们返回模型模型前失去原后果,你应该应用 raw
办法:
User::search()->raw();
搜寻查问通常会在模型的 searchableAs 办法指定的索引上执行。当然,你也能够应用 within 办法指定应该搜寻的自定义索引:
$orders = User::search()
->within('whereof_user')
->get();
Where 语句
Scout 容许你在搜寻查问中减少简略的「where」语句。目前,这些语句只反对根本的数值等式查看,并且次要是用于依据拥有者的 ID 进行的范畴搜寻查问。因为搜寻索引不是关系型数据库,因而以后不反对更高级的「where」语句:
User::search()->where('user_id', 1)->get();
分页
除了检索模型的汇合,你也能够应用 paginate 办法对搜寻后果进行分页。这个办法会返回一个就像 传统的模型查问分页 一样的 Paginator 实例:
User::search()->paginate();
你能够通过将数量作为第一个参数传递给 paginate 办法来指定每页检索多少个模型:
User::search()->paginate(15);
自定义引擎
如果内置的 Scout 搜索引擎不能满足你的需要,你能够写自定义的引擎并且将它注册到 Scout。你的引擎须要继承 whereof\think\scout\Engine
抽象类,这个抽象类蕴含了你自定义的引擎必须要实现的十种形象办法:
abstract public function update(Collection $models): void;
abstract public function delete(Collection $models): void;
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, int $perPage, int $page);
abstract public function mapIds($results): Collection;
abstract public function map(Builder $builder, $results, Model $model): Collection;
abstract public function getTotalCount($results): int;
abstract public function flush(Model $model): void;
abstract public function createIndex($name, array $options = []);
abstract public function deleteIndex($name);
注册引擎
一旦你写好了自定义引擎,您就能够在配置文件中指定引擎了。举个例子,如果你写好了一个 MySqlSearchEngine,您就能够在配置文件中这样写:
<?php
return ['default' => env('SCOUT_DRIVER', 'mysql'),
'soft_delete' => false,
'engine' => [
'mysql' => [
'driver' => MySqlSearchEngine::class,
'prefix' => '',
]
],
];