everzel / elasticsearch-query-builder
使用流畅的 PHP API 构建 和 执行 Elasticsearch 搜索查询
Requires
- php: ^7.1
Requires (Dev)
- elasticsearch/elasticsearch: ^7.12
- friendsofphp/php-cs-fixer: ^2.17
- phpunit/phpunit: ^9.5
- spatie/ray: ^1.10
- vimeo/psalm: ^4.3
README
使用流畅的 PHP API 构建 和 执行 ElasticSearch 查询
这个包是一个轻量级的 ElasticSearch 查询构建器。它专门为我们自己的 elasticsearch-search-string-parser 构建,因此覆盖了大多数用例,但可能缺少某些功能。如果您需要任何特定的功能,我们始终欢迎您提交 PR!
use Everzel\ElasticsearchQueryBuilder\Aggregations\MaxAggregation; use Everzel\ElasticsearchQueryBuilder\Builder; use Everzel\ElasticsearchQueryBuilder\Queries\MatchQuery; $client = Elasticsearch\ClientBuilder::create()->build(); $companies = (new Builder($client)) ->index('companies') ->addQuery(MatchQuery::create('name', 'spatie', fuzziness: 3)) ->addAggregation(MaxAggregation::create('score')) ->search();
支持我们
我们投入了大量资源来创建 最佳开源包。您可以通过 购买我们的付费产品之一 来支持我们。
我们非常感激您从家乡寄给我们明信片,注明您正在使用我们哪些包。您可以在 我们的联系页面 上找到我们的地址。我们将发布所有收到的明信片在我们的 虚拟明信片墙上。
安装
您可以通过 composer 安装此包
composer require everzel/elasticsearch-query-builder
基本用法
您真正需要与之交互的类只有一个,那就是 Everzel\ElasticsearchQueryBuilder\Builder
类。它需要通过构造函数传入一个 \Elasticsearch\Client
。请参阅 ElasticSearch SDK 文档 以了解如何连接到您的 ElasticSearch 集群。
Builder
类包含一些用于 添加查询、聚合、排序、字段 以及一些用于 分页 的额外方法。您可以在下面阅读更多关于这些方法的内容。一旦完全构建了查询,您可以使用 $builder->search()
来执行查询,或使用 $builder->getPayload()
来获取 ElasticSearch 的原始负载。
use Everzel\ElasticsearchQueryBuilder\Queries\RangeQuery; use Everzel\ElasticsearchQueryBuilder\Builder; $client = Elasticsearch\ClientBuilder::create()->build(); $builder = new Builder($client); $builder->addQuery(RangeQuery::create('age')->gte(18)); $results = $builder->search(); // raw response from ElasticSearch
添加查询
您可以使用 $builder->addQuery()
方法将任何可用的 Query
类型添加到构建器中。可用的查询类型可以在下面找到,或在此存储库的 src/Queries
目录中找到。每个 Query
都有一个静态的 create()
方法来传递其最重要的参数。
以下查询类型可用
ExistsQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\ExistsQuery::create('terms_and_conditions');
MatchQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\MatchQuery::create('name', 'john doe', fuzziness: 2);
MultiMatchQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\MultiMatchQuery::create('john', ['email', 'email'], fuzziness: 'auto');
NestedQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\NestedQuery::create( 'user', new \Everzel\ElasticsearchQueryBuilder\Queries\MatchQuery('name', 'john') );
RangeQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-range-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\RangeQuery::create('age') ->gte(18) ->lte(1337);
TermQuery
https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\TermQuery::create('user.id', 'flx');
WildcardQuery
[https://elastic.ac.cn/guide/cn/elasticsearch/reference/current/query-dsl-wildcard-query.html](https://elastic.ac.cn. elastic.co/guide/cn/elasticsearch/reference/current/query-dsl-wildcard-query.html)
\Everzel\ElasticsearchQueryBuilder\Queries\WildcardQuery::create('user.id', '*doe');
BoolQuery
https://elastic.ac.cn/guide/cn/elasticsearch/reference/current/query-dsl-bool-query.html
\Everzel\ElasticsearchQueryBuilder\Queries\BoolQuery::create() ->add($matchQuery, 'must_not') ->add($existsQuery, 'must_not');
链式调用多个查询
可以在一个 Builder
上链式调用多个 addQuery()
调用。在内部,它们将被添加到一个 BoolQuery
中,其出现类型为 must
。通过传递 addQuery()
方法的第二个参数,您可以选择不同的出现类型
$builder ->addQuery( MatchQuery::create('name', 'billie'), 'must_not' // available types: must, must_not, should, filter ) ->addQuery( MatchQuery::create('team', 'eillish') );
有关布尔查询及其出现类型的更多信息,请参阅 ElasticSearch 文档。
添加聚合
可以使用 $builder->addAggregation()
方法将任何可用的 Aggregation
添加到构建器中。可用的聚合类型可以在下面找到或在当前仓库的 src/Aggregations
目录中找到。每个 Aggregation
都有一个静态的 create()
方法来传递其最重要的参数,有时还有一些额外的方法。
use Everzel\ElasticsearchQueryBuilder\Aggregations\TermsAggregation; use Everzel\ElasticsearchQueryBuilder\Builder; $results = (new Builder(Elasticsearch\ClientBuilder::create()->build())) ->addAggregation(TermsAggregation::create('genres', 'genre')) ->search(); $genres = $results['aggregations']['genres']['buckets'];
以下查询类型可用
CardinalityAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\CardinalityAggregation::create('team_agg', 'team_name');
FilterAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\FilterAggregation::create( 'tshirts', \Everzel\ElasticsearchQueryBuilder\Queries\TermQuery::create('type', 'tshirt'), \Everzel\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'price') );
MaxAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'price');
MinAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\MinAggregation::create('min_price', 'price');
NestedAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\NestedAggregation::create( 'resellers', 'resellers', \Everzel\ElasticsearchQueryBuilder\Aggregations\MinAggregation::create('min_price', 'resellers.price'), \Everzel\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'resellers.price'), );
ReverseNestedAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\ReverseNestedAggregation::create( 'name', ...$aggregations );
TermsAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\TermsAggregation::create( 'genres', 'genre' ) ->size(10) ->order(['_count' => 'asc']) ->missing('N/A') ->aggregation(/* $subAggregation */);
TopHitsAggregation
\Everzel\ElasticsearchQueryBuilder\Aggregations\TopHitsAggregation::create( 'top_sales_hits', size: 10, );
添加排序
Builder(以及一些聚合)有一个 addSort()
方法,该方法接受一个 Sort
实例来对结果进行排序。您可以在 ElasticSearch 文档 中了解更多有关排序如何工作的信息。
use Everzel\ElasticsearchQueryBuilder\Sorts\Sort; $builder ->addSort(Sort::create('age', Sort::DESC)) ->addSort( Sort::create('score', Sort::ASC) ->unmappedType('long') ->missing(0) );
检索特定字段
可以使用 fields()
方法来请求从结果文档中检索特定字段,而不返回整个 _source
条目。您可以在 ElasticSearch 文档 中了解更多有关字段参数的详细信息。
$builder->fields('user.id', 'http.*.status');
分页
最后,Builder 还具有相应的 ElasticSearch 搜索参数的 size()
和 from()
方法。这些可以用于构建分页搜索。查看以下示例以获得大致了解
use Everzel\ElasticsearchQueryBuilder\Builder; $pageSize = 100; $pageNumber = $_GET['page'] ?? 1; $pageResults = (new Builder(\Elasticsearch\ClientBuilder::create())) ->size($pageSize) ->from(($pageNumber - 1) * $pageSize) ->search();
测试
composer test
变更日志
请参阅 CHANGELOG 了解最近更改的更多信息。
贡献
请参阅 CONTRIBUTING 了解详细信息。
安全漏洞
请参阅我们如何报告安全漏洞的 安全策略。
鸣谢
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。