lavatech / scout-elasticsearch-driver
Laravel Scout 的 Elasticsearch 驱动程序
Requires
- php: ^7.1.|^8.0
- elasticsearch/elasticsearch: >=7.0 <=7.17
- laravel/scout: ^7.0|^8.0|^9.0|^10.0
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^7.0|^8.0
- dev-master
- 4.4.2
- 4.4.1
- v4.4.0
- v4.3.1
- v4.3.0
- v4.2.3
- v4.2.2
- v4.2.1
- v4.2.0
- v4.1.0
- v4.0.5
- v4.0.4
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v3.13.0
- v3.12.0
- v3.11.0
- v3.10.0
- v3.9.1
- v3.9.0
- v3.8.2
- v3.8.1
- v3.8.0
- v3.7.1
- v3.7.0
- v3.6.1
- v3.6.0
- v3.5.0
- v3.4.1
- v3.4.0
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.1
- v3.2.0
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.0
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.0
- v2.0.1
- v2.0.0
- v1.3.1
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.1
- v1.1.0
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
This package is auto-updated.
Last update: 2024-09-22 11:08:53 UTC
README
💥 介绍一个全新的 Laravel Elasticsearch 生态系统。 💥
此包提供了在 Elasticsearch 中搜索和过滤数据的先进功能。查看其 功能!
内容
功能
- 一种简单的方法来 配置 和 创建 Elasticsearch 索引。
- 为每个 模型 提供完全可配置的映射。
- 可以自动添加新字段到现有映射,或者使用 artisan 命令。
- 多种方式来实现您的搜索算法:使用 搜索规则 或原始搜索。
- 各种过滤器类型 使搜索查询更具体。
- 从旧索引到新索引的零停机迁移。
- 批量索引,见 配置部分。
要求
该包已在以下配置下进行了测试
- PHP 版本 >=7.1.3, <=7.3
- Laravel 框架版本 >=5.8, <=6
- Elasticsearch 版本 >=7
安装
使用 composer 安装包
composer require babenkoivan/scout-elasticsearch-driver
如果您正在使用 Laravel 版本 <= 5.4 或 禁用包发现,请将以下提供者在 config/app.php
中添加
'providers' => [
Laravel\Scout\ScoutServiceProvider::class,
ScoutElastic\ScoutElasticServiceProvider::class,
]
配置
要配置此包,您需要首先发布设置
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
php artisan vendor:publish --provider="ScoutElastic\ScoutElasticServiceProvider"
然后,在 config/scout.php
文件中将驱动设置设置为 elastic
(或将在 .env
中设置 SCOUT_DRIVER=elastic
)并配置驱动本身在 config/scout_elastic.php
文件中。可用的选项包括
选项 | 描述 |
---|---|
client | 构建 Elasticsearch 客户端的设置哈希。更多信息请参阅 此处。默认主机设置为 localhost:9200 。 |
update_mapping | 指定是否自动更新映射的选项。默认设置为 true 。 |
indexer | 对于单文档索引设置为 single ,对于批量文档索引设置为 bulk 。默认设置为 single 。 |
document_refresh | 此选项控制更新的文档何时出现在搜索结果中。可以是 'true' 、'false' 、'wait_for' 或 null 。更多关于此选项的详细信息请参阅 此处。默认设置为 null 。 |
注意,如果您使用批量文档索引,您可能希望更改块大小,您可以在 config/scout.php
文件中这样做。
索引配置器
索引配置器类用于设置Elasticsearch索引的设置。要创建新的索引配置器,请使用以下Artisan命令
php artisan make:index-configurator MyIndexConfigurator
它将在您的项目中的app
文件夹中创建一个名为MyIndexConfigurator.php
的文件。您可以在以下示例中指定索引名称和设置
<?php
namespace App;
use ScoutElastic\IndexConfigurator;
class MyIndexConfigurator extends IndexConfigurator
{
// It's not obligatory to determine name. By default it'll be a snaked class name without `IndexConfigurator` part.
protected $name = 'my_index';
// You can specify any settings you want, for example, analyzers.
protected $settings = [
'analysis' => [
'analyzer' => [
'es_std' => [
'type' => 'standard',
'stopwords' => '_spanish_'
]
]
]
];
}
有关索引设置的更多信息,您可以在Elasticsearch文档的索引管理部分中找到。
要创建索引,只需运行Artisan命令
php artisan elastic:create-index "App\MyIndexConfigurator"
注意,每个可搜索模型都需要自己的索引配置器。
在Elasticsearch 6.0.0或更高版本中创建的索引可能只能包含单个映射类型。在5.x版本中使用多个映射类型创建的索引将在Elasticsearch 6.x版本中继续按之前的方式运行。映射类型将在Elasticsearch 7.0.0中完全删除。
更多信息请访问此处。
可搜索模型
要创建一个具有在Elasticsearch索引中执行搜索请求能力的模型,请使用以下命令
php artisan make:searchable-model MyModel --index-configurator=MyIndexConfigurator
执行命令后,您将在app
文件夹中找到名为MyModel.php
的文件
<?php
namespace App;
use ScoutElastic\Searchable;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
use Searchable;
protected $indexConfigurator = MyIndexConfigurator::class;
protected $searchRules = [
//
];
// Here you can specify a mapping for model fields
protected $mapping = [
'properties' => [
'title' => [
'type' => 'text',
// Also you can configure multi-fields, more details you can find here https://elastic.ac.cn/guide/en/elasticsearch/reference/current/multi-fields.html
'fields' => [
'raw' => [
'type' => 'keyword',
]
]
],
]
];
}
每个可搜索模型代表一个Elasticsearch类型。默认情况下,类型名称与表名称相同,但您可以通过searchableAs
方法设置任何类型的名称。您还可以通过toSearchableArray
方法指定将由驱动程序索引的字段。有关这些选项的更多信息,您可以在scout官方文档中找到。
您可以在MyModel
类中设置的最后一个重要选项是$searchRules
属性。它允许您为模型设置不同的搜索算法。我们将在搜索规则部分中更详细地介绍它。
在模型中设置映射后,您可以更新Elasticsearch类型的映射
php artisan elastic:update-mapping "App\MyModel"
用法
一旦创建了索引配置器、Elasticsearch索引和可搜索模型,您就准备就绪了。现在您可以根据文档索引和搜索数据。
基本搜索用法示例
// set query string
App\MyModel::search('phone')
// specify columns to select
->select(['title', 'price'])
// filter
->where('color', 'red')
// sort
->orderBy('price', 'asc')
// collapse by field
->collapse('brand')
// set offset
->from(0)
// set limit
->take(10)
// get results
->get();
如果您只需要查询的匹配数,请使用count
方法
App\MyModel::search('phone')
->count();
如果您需要加载关系,请使用with
方法
App\MyModel::search('phone')
->with('makers')
->get();
除了标准功能外,此包还提供了您可以在不指定查询字符串的情况下在Elasticsearch中过滤数据的功能
App\MyModel::search('*')
->where('id', 1)
->get();
您还可以覆盖模型的搜索规则
App\MyModel::search('Brazil')
->rule(App\MySearchRule::class)
->get();
并使用各种where
条件
App\MyModel::search('*')
->whereRegexp('name.raw', 'A.+')
->where('age', '>=', 30)
->whereExists('unemployed')
->get();
并且过滤掉得分低于min_score的结果
App\MyModel::search('sales')
->minScore(1.0)
->get();
并且添加更复杂的排序(例如geo_distance)
$model = App\MyModel::search('sales')
->orderRaw([
'_geo_distance' => [
'coordinates' => [
'lat' => 51.507351,
'lon' => -0.127758
],
'order' => 'asc',
'unit' => 'm'
]
])
->get();
// To retrieve sort result, use model `sortPayload` attribute:
$model->sortPayload;
最后,如果您想发送自定义请求,可以使用searchRaw
方法
App\MyModel::searchRaw([
'query' => [
'bool' => [
'must' => [
'match' => [
'_all' => 'Brazil'
]
]
]
]
]);
此查询将返回原始响应。
控制台命令
以下列出了可用的Artisan命令
命令 | 参数 | 描述 |
---|---|---|
make:index-configurator | name - 类的名称 | 创建新的Elasticsearch索引配置器。 |
make:searchable-model | name - 类的名称 | 创建新的可搜索模型。 |
make:search-rule | name - 类的名称 | 创建新的搜索规则。 |
elastic:create-index | index-configurator - 索引配置器类 | 创建Elasticsearch索引。 |
elastic:update-index | index-configurator - 索引配置器类 | 更新Elasticsearch索引的设置和映射。 |
elastic:drop-index | index-configurator - 索引配置器类 | 删除Elasticsearch索引。 |
elastic:update-mapping | model - 模型类 | 更新模型映射。 |
elastic:migrate-model | model - 模型类,target-index - 要迁移的索引名称 | 将模型迁移到另一个索引。 |
要获取详细说明和所有可用选项,请在命令行中运行 php artisan help [命令]
。
搜索规则
搜索规则是一个描述搜索查询如何执行的类。要创建搜索规则,请使用以下命令
php artisan make:search-rule MySearchRule
在文件 app/MySearchRule.php
中,您将找到一个类定义
<?php
namespace App;
use ScoutElastic\SearchRule;
class MySearch extends SearchRule
{
// This method returns an array, describes how to highlight the results.
// If null is returned, no highlighting will be used.
public function buildHighlightPayload()
{
return [
'fields' => [
'name' => [
'type' => 'plain'
]
]
];
}
// This method returns an array, that represents bool query.
public function buildQueryPayload()
{
return [
'must' => [
'match' => [
'name' => $this->builder->query
]
]
];
}
}
您可以在这里了解更多关于布尔查询的信息,以及如何在这里了解高亮显示。
默认搜索规则返回以下有效负载
return [
'must' => [
'query_string' => [
'query' => $this->builder->query
]
]
];
这意味着默认情况下,当您在一个模型上调用 search
方法时,它会尝试在任何字段中查找查询字符串。
要确定模型的默认搜索规则,只需添加一个属性
<?php
namespace App;
use ScoutElastic\Searchable;
use Illuminate\Database\Eloquent\Model;
class MyModel extends Model
{
use Searchable;
// You can set several rules for one model. In this case, the first not empty result will be returned.
protected $searchRules = [
MySearchRule::class
];
}
您还可以在查询构建器中设置搜索规则
// You can set either a SearchRule class
App\MyModel::search('Brazil')
->rule(App\MySearchRule::class)
->get();
// or a callable
App\MyModel::search('Brazil')
->rule(function($builder) {
return [
'must' => [
'match' => [
'Country' => $builder->query
]
]
];
})
->get();
要获取高亮显示,请使用模型的 highlight
属性
// Let's say we highlight field `name` of `MyModel`.
$model = App\MyModel::search('Brazil')
->rule(App\MySearchRule::class)
->first();
// Now you can get raw highlighted value:
$model->highlight->name;
// or string value:
$model->highlight->nameAsString;
可用过滤器
您可以使用不同类型的过滤器
方法 | 示例 | 描述 |
---|---|---|
where($field, $value) | where('id', 1) | 检查是否等于一个简单值。 |
where($field, $operator, $value) | where('id', '>=', 1) | 根据给定的规则过滤记录。可用运算符:=, <, >, <=, >=, <>。 |
whereIn($field, $value) | whereIn('id', [1, 2, 3]) | 检查值是否在一组值中。 |
whereNotIn($field, $value) | whereNotIn('id', [1, 2, 3]) | 检查值是否不在一组值中。 |
whereBetween($field, $value) | whereBetween('price', [100, 200]) | 检查值是否在范围内。 |
whereNotBetween($field, $value) | whereNotBetween('price', [100, 200]) | 检查值是否不在范围内。 |
whereExists($field) | whereExists('unemployed') | 检查值是否已定义。 |
whereNotExists($field) | whereNotExists('unemployed') | 检查值是否未定义。 |
whereMatch($field, $value) | whereMatch('tags', 'travel') | 过滤匹配精确值的记录。您可以在这里找到更多关于语法的说明。 |
whereNotMatch($field, $value) | whereNotMatch('tags', 'travel') | 过滤不匹配精确值的记录。您可以在这里找到更多关于语法的说明。 |
whereRegexp($field, $value, $flags = 'ALL') | whereRegexp('name.raw', 'A.+') | 根据给定的正则表达式过滤记录。您可以在这里找到更多关于语法的说明。 |
whereGeoDistance($field, $value, $distance) | whereGeoDistance('location', [-70, 40], '1000m') | 根据给定的点和距离过滤记录。您可以在这里找到更多关于语法的说明。 |
whereGeoBoundingBox($field, array $value) | whereGeoBoundingBox('location', ['top_left' => [-74.1, 40.73], 'bottom_right' => [-71.12, 40.01]]) | 在给定的边界内过滤记录。您可以在这里找到更多关于语法的说明。 |
whereGeoPolygon($field, array $points) | whereGeoPolygon('location', [[-70, 40],[-80, 30],[-90, 20]]) | 在给定的多边形内过滤记录。您可以在这里找到更多关于语法的说明。 |
whereGeoShape($field, array $shape, $relation = 'INTERSECTS') | whereGeoShape('shape', ['type' => 'circle', 'radius' => '1km', 'coordinates' => [4, 52]], 'WITHIN') | 在给定的形状内过滤记录。更多关于语法的详情请参见这里。 |
在大多数情况下,使用原始字段来过滤记录更好,即未分析的字段。
零停机迁移
如您所知,在Elasticsearch中,您不能更改已创建字段的类型。在这种情况下,唯一的选择是创建一个新的索引,包含必要的映射,并将您的模型导入到新索引中。
迁移可能需要相当长的时间,因此为了在过程中避免停机时间,驱动程序从旧索引读取并写入新索引。一旦迁移完成,它开始从新索引读取,并删除旧索引。这就是artisan elastic:migrate-model
命令的工作方式。
在运行命令之前,请确保您的索引配置器使用ScoutElastic\Migratable
特性。如果不是,请添加特性并使用索引配置器类名作为参数运行artisan elastic:update-index
命令。
php artisan elastic:update-index "App\MyIndexConfigurator"
准备好后,在模型映射中进行更改,并使用模型类作为第一个参数,使用期望的索引名称作为第二个参数,运行elastic:migrate-model
命令。
php artisan elastic:migrate-model "App\MyModel" my_index_v2
注意,如果您只需要在映射中添加新字段,请使用elastic:update-mapping
命令。
调试
有两种方法可以帮助您分析搜索查询的结果
-
App\MyModel::search('Brazil') ->explain();
-
App\MyModel::search('Brazil') ->profile();
这两种方法都返回ES的原始数据。
此外,您可以通过调用buildPayload
方法来获取将被发送到ES的查询负载。
App\MyModel::search('Brazil')
->buildPayload();
注意,由于一个查询中可能使用多个搜索规则,该方法返回一个负载集合。
替代方案
最近,我发布了一个新的Elasticsearch生态系统,它包括
- Elastic Scout Driver - Laravel Scout的通用Elasticsearch驱动程序。如果您需要在Laravel应用程序中构建简单的搜索,它非常合适。
- Elastic Scout Driver Plus - Elastic Scout Driver的扩展。如果您想利用布尔查询、高亮显示等Elasticsearch功能,这是一个不错的选择。
- Elastic Migrations - 一种创建、删除或更新Elasticsearch索引模式并与其他团队成员共享的简单方法。它具有与Laravel数据库迁移相当相似的用户界面。
如果您对其中任何一个感兴趣并想了解更多详情,请阅读Laravel应用程序中Elasticsearch的终极指南。这篇文章对提到的包进行了很好的概述,并提供了使用示例。
常见问题解答
- 为什么你创建了一个新的包而不是新的
scout-elasticsearch-driver
版本?-我不想再创建一个全功能的包,很明显,这样做会导致关注点混乱,与其他Scout驱动程序不兼容,难以测试和开发等。由于Elastic Scout Driver是一个通用驱动程序,并没有实现所有的scout-elasticsearch-driver
功能,所以称它为新的scout-elasticsearch-driver
版本是不正确的。 - 这对scout-elasticsearch-driver意味着什么?-目前它由社区维护(感谢@iget-esoares和@lucamichot让项目保持活力🎉)。我希望他们将继续为项目做出贡献,并在未来带来新的
scout-elasticsearch-driver
版本。