ccennis / larelastic
elasticsearch和索引的通用包装器
Requires
- php: ^8.2
- elasticsearch/elasticsearch: ^7.16
- laravel/scout: ^8.0|^9.0
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^10.1
This package is not auto-updated.
Last update: 2024-09-26 12:43:15 UTC
README
一个索引和查询包,使用Laravel Scout作为核心,创建、维护和搜索弹性实例。
内容
安装
Laravel
在config/app.php中添加第三方服务提供者
Larelastic\Elastic\Providers\ElasticServiceProvider::class
在config/app.php中添加第三方别名
'Elastic' => Larelastic\Elastic\Facades\Elastic::class
获取配置文件
php artisan vendor:publish
将以下变量添加到您的.env文件中
ELASTICSEARCH_HOST=http://elastic:9200 ELASTICSEARCH_PORT=9200 SCOUT_DRIVER=elastic SCOUT_ELASTIC_HOST=http://elastic:9200
索引
(对于全新安装 - 如果索引已存在,请跳过第3步)
由于此包依赖于模型和索引配置器以创建、搜索和维护索引,因此您必须运行以下命令以生成和设置适当的对象。
1.) 创建一个indexConfigurator模型(在本例中为"Tattoo")
php artisan make:index-configurator TattooIndexConfigurator
2.) 创建您的可搜索模型
php artisan make:searchable-model Product --index-configurator=TattooIndexConfigurator
3.) 使用模型路径创建Elastic索引php artisan elastic:create-index "App\Models\Tattoo"
索引
4.) 向索引添加数据
php artisan scout:import "App\Models\Tattoo"
迁移到新索引
php artisan elastic:migrate "App\MyModel" my_index_v2
此过程创建了一个新索引,从先前的索引导入所有数据,然后将旧索引通过别名链接到新索引。
更新映射
php artisan elastic:update-mapping "App\\Models\MyModel"
更新索引
php artisan elastic:update-index "App\Models\MyModelConfigurator"
删除索引
php artisan elastic:drop-index "App\Models\MyModel"
其他配置选项
在您的指定模型中,您可能想使用方法
public function searchableQuery()
{
return $self->newQuery();
}
这将使您能够根据需要微调发送到Elastic的实际查询,如果您需要预加载或指定关系。
用法和示例
Where/OrWhere查询使用bool方法(must
、must_not
和should
)。语法旨在类似于Eloquent,但必须使用search
特性来区分实际的Eloquent。
有效运算符
示例Where查询
$response = Tattoo::search()->where('name', 'mold')->get(); $response = Tattoo::search()->where('name', '=', 'mold')->get();
以上两个查询都有效。默认运算符是'=',除非提供。
示例OrWhere查询
$response = Tattoo::search()->orWhere(['name', '=', 'mold'],['name', '=', 'Element'])->get();
接受两个数组,使用Elastic的should
bool运算符。等价于"找到这个或那个"。
$response = Tattoo::search()->orWhere(function($query, $boolean){ $query->where('name', '=','Mold', $boolean) ->where('model', '=','test', $boolean); return $query; })->orWhere(function($query, $boolean){ $query->where('name', '=','element', $boolean) ->where('model', '=','test', $boolean); return $query; })->get();
闭包,使用Elastic的should
bool运算符下的多个分组。等价于"找到(这个和那个)或(这个和那个)"。
示例Multimatch查询
$response = Tattoo::search()->whereMulti(['name', 'model'],'=','Mold')->get();
这使用了multimatch弹性函数,接收一个字段数组。默认搜索类型是短语前缀,但可以接受参数进行覆盖,例如best_fields
$response = Tattoo::search()->whereMulti(['name', 'model'],'=','Mold', 'best_fields')->get();
分页
$response = Tattoo::search()->whereMulti(['name', 'model'],'=','Mold')->paginate(20);
分页功能与eloquent中的功能类似。它会在响应中包装Paginator Length Aware元数据字段
first_page_url: "http://myProject.com?page=1",
from: 1,
last_page: 2,
last_page_url: "http://myProject.com?page=3",
next_page_url: "http://myProject.com?page=2",
path: "http://myProject.com",
per_page: 20,
prev_page_url: null,
to: 2,
total: 36
排序
简单排序
$response = Tattoo::search()->where('name', 'mold') sort->('name','desc')->get()
默认排序为升序,可以堆叠进行多次排序。
如果您需要指定排序字段的字段类型(例如 'keyword' 或 'raw'),您可以将其作为参数包含在内
$response = Tattoo::search()->where('name', 'mold') sort->('name', 'desc', 'keyword')->get()
在您已经查询嵌套对象并希望确保数据类型单独列出时,上述内容可能是必要的。
地理排序
基于经纬度的距离排序。Elastic中的示例查询
{ "sort": [{ "_geo_distance": { "location": { "lat": 40, "lon": -70 }, "order": "asc", "unit": "mi", "mode": "min", "distance_type": "arc", "ignore_unmapped": true } ]} }
为了在包中使用此功能,您可以使用以下语法
$data = [ 'field' => 'location_lat_long', 'lat' => $lat, 'long' => $lat, ]; $this->search->buildGeoSort($data);
还支持以原始语法返回距离查询,这可以在顶层OR语句中使用。示例
$latLongArray = explode(",", $this->user->location_lat_long); $response['bool']['must'] = $this->search->whereDistanceSyntax('artist.location_lat_long', $latLongArray[0], $latLongArray[1], '25mi'); return $response;
在数据数组中传递的有效字段如上所述在Elastic查询中。
单位的有效参数包括:mi(英里)、in(英寸)、yd(码)、km(千米)、cm(厘米)、mm(毫米)。
有两种距离计算模式:arc(默认)和plane。arc计算是最准确的。
{ ```php mi (miles), in (inches), yd (yards), km (kilometers), cm (centimeters), mm (millimeters). #### <a id="aggs"></a>Aggregation (aggs) ```php $response = Tattoo::search()->where('name', 'mold') ->rollup('card_color')->get();
对aggs的初始支持接受一个列名并创建桶来计数所有匹配项。结果集将位于“aggs”对象下,如下所示
{ aggs: { agg_field: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [{ key: "G", doc_count: 35 }, { key: "B", doc_count: 1 } ] } } }