matchish / laravel-scout-elasticsearch
使用ElasticSearch和Laravel Scout在多个模型中进行搜索
Requires
- php: ^8.0.12|^8.1
- elasticsearch/elasticsearch: ^8.0
- handcraftedinthealps/elasticsearch-dsl: ^8.0
- laravel/scout: ^8.0|^9.0|^10.0
- roave/better-reflection: ^4.3|^5.0|^6.18|^6.36
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/legacy-factories: ^1.0
- orchestra/testbench: ^6.17|^7.0|^8.0
- php-http/guzzle7-adapter: ^1.0
- phpunit/phpunit: ^9.4.0
Suggests
- mateusjunges/laravel-trackable-jobs: Required when using --parallel option in ImportCommand.
- dev-master
- 8.x-dev
- 8.0.0-alpha.2
- 8.0.0-alpha.1
- v7.7.0
- v7.6.2
- v7.6.1
- v7.6.0
- v7.5.0
- v7.4.0
- v7.3.0
- v7.2.2
- v7.2.1
- v7.2.0
- v7.1.0
- v7.0.0
- V6.0.2
- v6.0.1
- v6.0.0
- 5.x-dev
- v5.0.3
- v5.0.2
- 5.0.1
- 5.0.0
- 4.0.9
- 4.0.8
- 4.0.7
- 4.0.5
- 4.0.4
- 4.0.3
- 4.0.1
- 4.0.0
- 3.x-dev
- 3.0.6
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.1.0
- 1.0.0
- dev-spike-es7-with-7.6.0
- dev-resolve-242
- dev-matchish-issue-227
- dev-github-actions
- dev-parallel-import
- dev-php8
- dev-analysis-nN7gwO
This package is auto-updated.
Last update: 2024-09-02 21:36:27 UTC
README
与乌克兰同在
UNITED24 启动了第一个针对地面机器人平台的活动筹集资金。机器人部队将拯救我们的军事人员和平民的生命。它们将成为物流设备、拖车、布雷车和排雷机器人,以及自毁机器人。它们将与人类并肩作战,为人类而战。
第一批机器人已经在战场上证明了它们的有效性。很快就会有更多。更多。
对于Laravel框架 < 6.0.0,请使用3.x分支
该包为将ElasticSearch集成到您的Laravel应用程序中提供了完美的起点。它经过精心设计,以简化在Laravel框架中使用ElasticSearch。
它建立在最新版本的Laravel Scout之上,这是官方的Laravel搜索包。使用此包,您可以自由利用Laravel Scout的所有出色功能,同时利用ElasticSearch的完整搜索体验。
如果您需要任何帮助,请通过stack overflow提问,这是首选和推荐的支持提问方式。
💕 特点
如果您喜欢这个包,请别忘了⭐它。🙏
- Laravel Scout 10.x支持
- Laravel Nova支持
- 在多个模型中进行搜索
- 零停机时间重新导入 - 在生产环境中导入数据非常简单。
- 预加载关系 - 加速您的导入。
- 并行导入以尽可能快地导入数据(目前为alpha版本)
- 一次性导入所有可搜索的模型。
- 为每个模型提供完全可配置的映射。
- 在查询中充分利用ElasticSearch的全部功能。
⚠️ 要求
- PHP版本 >= 8.0
- Laravel框架版本 >= 8.0.0
🚀 安装
使用composer安装包
composer require matchish/laravel-scout-elasticsearch
设置环境变量
SCOUT_DRIVER=Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine
该包使用官方包中的\ElasticSearch\Client
,但不会尝试对其进行配置,超出连接配置之外,因此您可以在应用程序服务提供程序中自由进行配置。但如果你现在不想这样做,你可以使用包中的Matchish\ElasticSearchServiceProvider
。
注册提供程序,将其添加到config/app.php
'providers' => [ // Other Service Providers \Matchish\ScoutElasticSearch\ElasticSearchServiceProvider::class ],
设置环境变量ELASTICSEARCH_HOST
ELASTICSEARCH_HOST=host:port
或使用逗号作为分隔符以分隔额外的节点
ELASTICSEARCH_HOST=host:port,host:port
您可以通过在您的环境中设置以下内容来禁用SSL验证
ELASTICSEARCH_SSL_VERIFICATION=false
并发布elasticsearch配置示例
php artisan vendor:publish --tag config
💡 用法
注意:此包增加了对Laravel Scout的功能,因此我们建议您首先阅读Scout文档。Scout的文档可以在Laravel网站上找到。
索引 设置 和 映射
当我们创建索引时,定义映射非常重要——不恰当的初步定义和映射可能会导致搜索结果错误。
为了定义索引的映射或设置,设置正确的配置值。
例如,如果方法 searchableAs
返回 products
字符串
映射的配置键应为
elasticsearch.indices.mappings.products
或者您可以使用配置键 elasticsearch.indices.mappings.default
指定默认映射
同样,您可以定义设置
对于索引 products
,它将是
elasticsearch.indices.settings.products
而对于默认设置
elasticsearch.indices.settings.default
预加载
为了加快导入速度,您可以使用全局范围在导入时预加载关系。
您应该在服务提供者中配置 ImportSourceFactory
(在 register
方法中)
use Matchish\ScoutElasticSearch\Searchable\ImportSourceFactory; ... public function register(): void { $this->app->bind(ImportSourceFactory::class, MyImportSourceFactory::class);
以下是 MyImportSourceFactory
的一个示例
namespace Matchish\ScoutElasticSearch\Searchable; final class MyImportSourceFactory implements ImportSourceFactory { public static function from(string $className): ImportSource { //Add all required scopes return new DefaultImportSource($className, [new WithCommentsScope()]); } } class WithCommentsScope implements Scope { /** * Apply the scope to a given Eloquent query builder. * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { $builder->with('comments'); } }
当您通过利用 Laravel Scout 提供的 toSearchableArray
方法保存模型时,也可以自定义您的索引数据
示例
class Product extends Model { use Searchable; /** * Get the indexable data array for the model. * * @return array */ public function toSearchableArray() { $with = [ 'categories', ]; $this->loadMissing($with); return $this->toArray(); } }
此示例将确保在保存模型时始终加载类别关系。
零停机重新导入
在生产环境中工作,为了在重新导入数据时保持现有的搜索体验,您也可以使用 scout:import
Artisan 命令
php artisan scout:import
该命令将创建一个新的临时索引,将所有模型导入其中,然后切换到该索引并删除旧索引。
搜索
为了与原始 scout 包完全兼容,此包不添加新方法。
那么我们如何构建复杂的查询呢?有两种方法。
默认情况下,当您将查询传递给 search
方法时,引擎将构建一个 query_string 查询,因此您可以构建这样的查询
Product::search('(title:this OR description:this) AND (title:that OR description:that)')
如果这不足以满足您的需求,您可以将回调传递给查询构建器
$results = Product::search('zonga', function(\Elastic\Elasticsearch\Client $client, $body) { $minPriceAggregation = new MinAggregation('min_price'); $minPriceAggregation->setField('price'); $maxPriceAggregation = new MaxAggregation('max_price'); $maxPriceAggregation->setField('price'); $brandTermAggregation = new TermsAggregation('brand'); $brandTermAggregation->setField('brand'); $body->addAggregation($minPriceAggregation); $body->addAggregation($brandTermAggregation); return $client->search(['index' => 'products', 'body' => $body->toArray()])->asArray(); })->raw();
注意:回调函数将获得两个参数。第一个是
$client
,它是来自 elasticsearch/elasticsearch 包的\Elastic\Elasticsearch\Client
类的对象。第二个是$body
,它是来自 ongr/elasticsearch-dsl 包的\ONGR\ElasticsearchDSL\Search
对象。所以,如您在上面的示例中所见,$client->search(....)
方法将返回一个\Elastic\Elasticsearch\Response\Elasticsearch
对象。您需要使用asArray()
方法来获取数组结果。否则,HitsIteratorAggregate
类将引发错误。您可以在 这里 查看问题。
条件
Scout 只支持 3 个条件:->where(column, value)
(严格相等)、->whereIn(column, array)
和 ->whereNotIn(column, array)
Product::search('(title:this OR description:this) AND (title:that OR description:that)') ->where('price', 100) ->whereIn('type', ['used', 'like new']) ->whereNotIn('type', ['new', 'refurbished']);
Scout 不支持任何运算符,但您可以将 ElasticSearch 术语(如 RangeQuery
)作为值传递给 ->where()
use ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery; Product::search('(title:this OR description:this) AND (title:that OR description:that)') ->where('price', new RangeQuery('price', [ RangeQuery::GTE => 100, RangeQuery::LTE => 1000, ]);
如果您只想使用 RangeQuery 进行搜索而不使用任何 query_string,则可以直接调用 search() 方法并将参数留空。
use ONGR\ElasticsearchDSL\Query\TermLevel\RangeQuery; Product::search() ->where('price', new RangeQuery('price', [ RangeQuery::GTE => 100, ]);
ElasticSearch 术语的完整列表在 vendor/handcraftedinthealps/elasticsearch-dsl/src/Query/TermLevel
中。
在多个模型中进行搜索
您可以使用MixedSearch
类来实现,只需将索引名称用逗号分隔后传递给within
方法。
MixedSearch::search('title:Barcelona or to:Barcelona') within(implode(',', [ (new Ticket())->searchableAs(), (new Book())->searchableAs(), ])) ->get();
在这个例子中,您将获得包含Ticket
和Book
模型的集合,其中票的到达城市或书籍标题为Barcelona
。
处理结果
通常,您的响应不是模型的集合,而是聚合或带有高亮的模型等。在这种情况下,您需要实现自己的HitsIteratorAggregate
实现,并将其绑定到服务提供者中。
🆓 许可证
Scout ElasticSearch是一个开源软件,遵循MIT许可协议MIT license。