god-jay / scout-elasticsearch
Requires
- php: >=7.0
- elasticsearch/elasticsearch: ^7.7
- laravel/scout: ^8.0
This package is auto-updated.
Last update: 2024-09-20 18:18:39 UTC
README
在 Laravel 应用程序中使用 Elasticsearch 与使用 Eloquent ORM 一样简单。
英语 | 简体中文
内容
安装
您可以通过 composer 安装此包
composer require god-jay/scout-elasticsearch
安装包后,您应使用 vendor:publish Artisan 命令发布 Scout 配置。此命令将 scout.php 配置文件发布到您的配置目录
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
然后添加
SCOUT_DRIVER=elastic
ELASTICSEARCH_HOST=your_es_host_ip:port
#Add if should auth es user
ELASTICSEARCH_USER=your_es_user
ELASTICSEARCH_PASS=your_es_pass
使用 Docker Compose 运行 es + kibana
如果您没有自己的 es 服务,您可以使用 docker compose 安装并运行 es + kibana
-
您首先应安装 docker compose: 安装 docker compose
-
然后在目录根运行该命令
docker-compose up -d
-
您可以通过
https://:5601浏览 kibana。 -
要停止 docker 容器,请在目录根运行该命令
docker-compose down
在您的 .env 文件中。
配置
假设有一个 posts 表和一个 Post 模型,简化后的表可能如下所示
在模型中使用 GodJay\ScoutElasticsearch\Searchable
namespace App\Models; use GodJay\ScoutElasticsearch\Searchable; use Illuminate\Database\Eloquent\Model; class Post extends Model { use Searchable; }
在模型中添加 searchableAs 函数
public function searchableAs() { //elasticsearch index name, you can set any name you like in the model return 'posts'; }
使用
创建 Elasticsearch 索引
在模型中添加 getElasticMapping 函数
然后运行 php artisan elastic:create-index "App\Models\Post"
有关更多详细信息,请参阅 创建索引 API
public function getElasticMapping() { return [ 'title' => [ 'type' => 'text', 'analyzer' => 'ik_max_word', 'search_analyzer' => 'ik_smart', ], 'content' => [ 'type' => 'text', 'analyzer' => 'ik_max_word', 'search_analyzer' => 'ik_smart', ], ]; }
Elasticsearch 索引将如下所示
{
"mapping": {
"_doc": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
}
将给定的模型导入到搜索索引中
如果您的表中已经存在许多行,并且您想将这些行导入到 Elasticsearch 中
在模型中添加 toSearchableArray 函数,然后运行 php artisan scout:import "App\Models\Post"
public function toSearchableArray() { return [ 'id' => $this->attributes['id'], 'title' => $this->attributes['title'], 'content' => strip_tags($this->attributes['content']), 'created_at' => $this->attributes['created_at'], ]; }
从上面的表中导入行后,Elasticsearch 索引将如下所示
{
"mapping": {
"_doc": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"created_at": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
}
从索引中清除模型的所有记录
运行 php artisan scout:flush "App\Models\Post"
添加记录
一旦您将 Searchable 特性添加到模型中,您只需保存模型实例,它就会自动添加到您的搜索索引中。
$post = new Post(); // ... $post->save();
更新记录
要更新可搜索的模型,您只需更新模型实例的属性并将模型保存到数据库中。
$post = Post::find(1); // Update the order... $post->save();
删除记录
要从索引中删除记录,请从数据库中删除模型。这种删除方式甚至与软删除模型兼容
$post = Post::find(1); $post->delete();
搜索
基础
$posts = Post::search('内容')->get();
分页
$posts = Post::search('内容')->paginate(10);
高亮显示
$post = Post::search('内容')->highlight(['title' => null, 'content' => null])->first();
搜索结果将是
App\Models\Post Object ( [table:protected] => ppp ... [attributes:protected] => [ [id] => 1 [title] => 标题 [content] => 文本内容 [created_at] => 2020-01-01 01:01:01 ] [relations:protected] => [ [highlight] => GodJay\ScoutElasticsearch\Highlight Object ( [attributes:protected] => [ [content] => [ [0] => 文本<em>内容</em> ] ] ) ] )
高级使用
ES 脚本排序
use GodJay\ScoutElasticsearch\ElasticsearchEngine; $posts = Post::search('', function (ElasticsearchEngine $engine, string $query, array $params) { $params['body']['sort'] = array_merge([[ '_script' => [ 'type' => 'number', 'script' => ['source' => "doc['field_a'].value * 0.7 + doc['field_b'].value * 0.3"], 'order' => 'desc' ] ]], $params['body']['sort'] ?? []); $engine->setQueryParams($params); return $engine; })->orderBy('id', 'desc')->where('field_c', 1)->get();
调试
use GodJay\ScoutElasticsearch\ElasticsearchEngine; $debug = Post::search('', function (ElasticsearchEngine $engine, string $query, array $params) { $params['body']['sort'] = array_merge([[ '_script' => [ 'type' => 'number', 'script' => ['source' => "doc['field_a'].value * 0.7 + doc['field_b'].value * 0.3"], 'order' => 'desc' ] ]], $params['body']['sort'] ?? []); $engine->setQueryParams($params); return $engine; })->orderBy('id', 'desc')->where('field_c', 1)->where('field_d', ['x', 'y'])->debugSearch();
结果将是
Array ( [result] => Illuminate\Database\Eloquent\Collection Object ... [query_params] => Array ... [exception] => ... )
$debug['query_params'] 的 json 字符串将是
{
"index": "posts",
"body": {
"sort": [
{
"_script": {
"type": "number",
"script": {
"source": "doc['field_a'].value * 0.7 + doc['field_b'].value * 0.3"
},
"order": "desc"
}
},
{
"id": "desc"
}
],
"query": {
"bool": {
"must": [
{
"match_phrase": {
"field_c": 1
}
},
{
"terms": {
"field_d": [
"x",
"y"
]
}
}
]
}
}
}
}