spatie/elasticsearch-query-builder

使用流畅的PHP API构建和执行Elasticsearch搜索查询

3.0.0 2024-05-06 09:04 UTC

This package is auto-updated.

Last update: 2024-09-06 09:53:18 UTC


README

Latest Version on Packagist Tests Total Downloads

本包是一个轻量级的ElasticSearch查询构建器。它专门为我们构建的elasticsearch-search-string-parser,因此涵盖了大多数用例,但可能缺少某些功能。如果您需要任何特定功能,我们始终欢迎PR!

use Spatie\ElasticsearchQueryBuilder\Aggregations\MaxAggregation;
use Spatie\ElasticsearchQueryBuilder\Builder;
use Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery;

$client = Elastic\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 spatie/elasticsearch-query-builder

注意 如果您正在使用elasticsearch/elasticsearch v7,您需要使用此包的v1

基本用法

您真正需要与之交互的类是Spatie\ElasticsearchQueryBuilder\Builder类。它需要一个通过构造函数传递的\Elastic\Elasticsearch\Client。查看ElasticSearch SDK文档以了解如何连接到您的ElasticSearch集群。

Builder类包含一些用于添加查询聚合排序字段和一些用于分页的额外方法。您可以在下面了解更多关于这些方法的信息。一旦完全构建查询,您可以使用$builder->search()来执行查询,或使用$builder->getPayload()来获取ElasticSearch的原始负载。

use Spatie\ElasticsearchQueryBuilder\Queries\RangeQuery;
use Spatie\ElasticsearchQueryBuilder\Builder;

$client = Elastic\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

\Spatie\ElasticsearchQueryBuilder\Queries\ExistsQuery::create('terms_and_conditions');

MatchQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-match-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery::create('name', 'john doe', fuzziness: 2, boost: 5.0);

MultiMatchQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\MultiMatchQuery::create('john', ['email', 'email'], fuzziness: 'auto');

NestedQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\NestedQuery::create(
    'user', 
    new \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery('name', 'john')
);

RangeQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-range-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\RangeQuery::create('age')
    ->gte(18)
    ->lte(1337);

TermQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\TermQuery::create('user.id', 'flx');

TermsQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\TermsQuery::create('user.id', ['flx', 'fly']);

WildcardQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\WildcardQuery::create('user.id', '*doe');

BoolQuery

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

\Spatie\ElasticsearchQueryBuilder\Queries\BoolQuery::create()
    ->add($matchQuery, 'must_not')
    ->add($existsQuery, 'must_not');

链式多个查询

一个Builder对象上可以链式调用多个addQuery()方法。在底层,这些调用会被添加到带有must发生类型的BoolQuery中。通过向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 Spatie\ElasticsearchQueryBuilder\Aggregations\TermsAggregation;
use Spatie\ElasticsearchQueryBuilder\Builder;

$results = (new Builder(Elastic\Elasticsearch\ClientBuilder::create()->build()))
    ->addAggregation(TermsAggregation::create('genres', 'genre'))
    ->search();

$genres = $results['aggregations']['genres']['buckets'];

以下查询类型可用:

CardinalityAggregation

\Spatie\ElasticsearchQueryBuilder\Aggregations\CardinalityAggregation::create('team_agg', 'team_name');

FilterAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\FilterAggregation::create(
    'tshirts',
    \Spatie\ElasticsearchQueryBuilder\Queries\TermQuery::create('type', 'tshirt'),
    \Spatie\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'price')
);

MaxAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'price');

MinAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\MinAggregation::create('min_price', 'price');

SumAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\SumAggregation::create('sum_price', 'price');

NestedAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\NestedAggregation::create(
    'resellers',
    'resellers',
    \Spatie\ElasticsearchQueryBuilder\Aggregations\MinAggregation::create('min_price', 'resellers.price'),
    \Spatie\ElasticsearchQueryBuilder\Aggregations\MaxAggregation::create('max_price', 'resellers.price'),
);

ReverseNestedAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\ReverseNestedAggregation::create(
    'name',
    ...$aggregations
);

TermsAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\TermsAggregation::create(
    'genres',
    'genre'
)
    ->size(10)
    ->order(['_count' => 'asc'])
    ->missing('N/A')
    ->aggregation(/* $subAggregation */);

TopHitsAggregation

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-hits-aggregation.html

\Spatie\ElasticsearchQueryBuilder\Aggregations\TopHitsAggregation::create(
    'top_sales_hits',
    size: 10,
);

添加排序

Builder(以及一些聚合)有一个addSort()方法,该方法接受一个Sort实例以对结果进行排序。有关排序的更多信息,请参阅ElasticSearch文档

use Spatie\ElasticsearchQueryBuilder\Sorts\Sort;

$builder
    ->addSort(Sort::create('age', Sort::DESC))
    ->addSort(
        Sort::create('score', Sort::ASC)
            ->unmappedType('long')
            ->missing(0)
    );

Nested sort

https://elastic.ac.cn/guide/en/elasticsearch/reference/current/sort-search-results.html#_nested_sorting_examples

use Spatie\ElasticsearchQueryBuilder\Sorts\NestedSort;

$builder
    ->addSort(
        NestedSort::create('books', 'books.rating', NestedSort::ASC)
    );

Nested sort with filter

use Spatie\ElasticsearchQueryBuilder\Sorts\NestedSort;
use Spatie\ElasticsearchQueryBuilder\Queries\BoolQuery;
use Spatie\ElasticsearchQueryBuilder\Queries\TermQuery;

$builder
    ->addSort(
        NestedSort::create(
            'books', 
            'books.rating', 
            NestedSort::ASC
        )->filter(BoolQuery::create()->add(TermQuery::create('books.category', 'comedy'))
    );

检索特定字段

可以使用fields()方法请求从结果文档中获取特定字段,而不返回整个_source条目。有关字段参数的详细信息,请参阅ElasticSearch文档

$builder->fields('user.id', 'http.*.status');

高亮显示

可以使用highlight()方法根据ElasticSearch文档中的规则在查询中添加高亮部分。

$highlightSettings = [
    'pre_tags' => ['<em>'],
    'post_tags' => ['</em>'],
    'fields' => [
        '*' => (object) []
    ]
];

$builder->highlight($highlightSettings);

后过滤

可以使用addPostFilterQuery()方法根据ElasticSearch文档中的规则向查询中添加后过滤布尔查询。

use Spatie\ElasticsearchQueryBuilder\Queries\TermsQuery;

$builder->addPostFilterQuery(TermsQuery::create('user.id', ['flx', 'fly']));

分页

最后,Builder还提供了相应的ElasticSearch搜索参数的size()from()方法。这些可以用于构建分页搜索。查看以下示例以获得大致了解。

use Spatie\ElasticsearchQueryBuilder\Builder;

$pageSize = 100;
$pageNumber = $_GET['page'] ?? 1;

$pageResults = (new Builder(Elastic\Elasticsearch\ClientBuilder::create()))
    ->size($pageSize)
    ->from(($pageNumber - 1) * $pageSize)
    ->search();

测试

composer test

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

安全漏洞

有关如何报告安全漏洞的信息,请参阅我们的安全策略

鸣谢

许可

MIT许可(MIT)。有关更多信息,请参阅许可文件