inpsyde / elastic-facets
提供API以访问Elasticsearch聚合,以构建分面搜索表单
Requires
- php: >=5.6
- guzzlehttp/psr7: ^1.3
- psr/http-message: ^1.0
Requires (Dev)
- inpsyde/monkery-test-case: dev-master
This package is auto-updated.
Last update: 2021-02-11 10:14:00 UTC
README
包正在建设中。API和架构可能发生变化!请关注 CHANGELOG.md
提供API以访问Elasticsearch(ES)聚合,以构建分面搜索表单。尽管聚合表达式API可以与其他Elasticsearch集成一起使用,但此插件实际上是建立在 Elasticpress 之上的。
未维护
注意: 此存储库不再维护。
目录
安装
使用Composer是使用此包的最佳方式
$ composer require inpsyde/elastic-facets:dev-master
用法
主查询的聚合
示例:计算默认分类(post_tag
和 category
)在默认搜索查询上的术语聚合。
namespace Example; use ElasticFacets\ElasticFacetsApi; use ElasticFacets\Aggregation\SingleFieldTerms; use ElasticFacets\AggregationField\EpTermTaxonomyAggregationField; use Psr\Http\Message\ServerRequestInterface; use WP_Query; /** * Register aggregations (runs during `pre_get_posts`of the main query) */ add_action( 'elastic_facets.register_aggregation', function( ElasticFacetsApi $ef, ServerRequestInterface $request, WP_Query $query ) { if ( ! $query->is_search() ) { return; } $cat_id = 'category'; $tag_id = 'post_tag'; $ef->add_aggregation( $cat_id, new SingleFieldTerms( new EpTermTaxonomyAggregationField( 'category' ) ) ); $ef->add_aggregation( $tag_id, new SingleFieldTerms( new EpTermTaxonomyAggregationField( 'post_tag' ) ) ); } ); /** * Somewhen after `pre_get_posts`, probably in the theme */ $ef = apply_filters( 'elastic_facets.get_registry', FALSE ); if ( ! $ef instanceof ElasticFacetsApi ) { return; } $category_terms = $ef->get_aggregates( $cat_id ); if ( $category_terms ) { foreach ( $category_terms->terms() as $term ) { $term->id(); // Numeric ID from the ES index, identical to the WP term ID $term->name(); // Term name $count = $category_terms->count( $term ); // Counted documents for this term } } // Same for post_tag terms
自定义查询的聚合
示例:查询WooCommerce产品分类术语 shoes
并计算产品属性(WooCommerce分类)pa_color
和 pa_size
的术语聚合以及最小和最大价格(文章元数据)。
namespace Example; use ElasticFacets\Aggregation\AbsoluteNumericRange; use ElasticFacets\Aggregation\SingleFieldTerms; use ElasticFacets\AggregationField\EpTermTaxonomyAggregationField; use ElasticFacets\AggregationField\RequestNumericRangeField; use ElasticFacets\ElasticFacets; use ElasticFacets\Type\AggregatedNumericRangesCollection; use ElasticFacets\Type\AggregatedTermsCollection; use WP_Query; $ef = ElasticFacets::create(); $ef ->add_aggregation( 'color', new SingleFieldTerms( new EpTermTaxonomyAggregationField( 'pa_color' ) ) ) ->add_aggregation( 'size', new SingleFieldTerms( new EpTermTaxonomyAggregationField( 'pa_size' ) ) ) ->add_aggregation( 'price', new AbsoluteNumericRange( new RequestNumericRangeField( 'meta._price.double', ElasticFacets::get_request(), 'price_range' ) ) ); $query = new WP_Query( [ 'post_type' => [ 'product' ], 'tax_query' => [ [ 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => [ 'shoes' ] ] ], 'posts_per_page' => 5, 'elastic_facets' => $facets, 'ep_integrate' => TRUE ] ); /* @var AggregatedTermsCollection | null $size */ $sizes = $ef->get_aggregates( 'size' ); /* @var AggregatedTermsCollection | null $colors */ $colors = $ef->get_aggregates( 'colors' ); /* @var AggregatedNumericRangesCollection | null $range_list */ $range_list = $ef->get_aggregates( 'price' ); if ( $range_list && ! empty( $range_list->ranges() ) ) { $price_range = current( $range_list->ranges() ); $price_range->min(); // Min price $price_range->max(); // Max price $range_list->count( $price_range ); // Number of products in this range }
RequestNumericRangeField
从给定的 ServerRequestInterface
对象中获取其最小/最大值,使用请求名称(第三个参数)。当聚合与特定价格范围的过滤器结合使用时,这可能很有用。
<?php $field = new RequestNumericRangeField( 'meta._price.double', ElasticFacets::get_request(), 'price_range' ); ?> <label for="min">Min</label> <input type="number" name="price_range[]" id="min" value="<?= esc_attr( $field->min() ) ?>" /> <label for="max">Max</label> <input type="number" name="price_range[]" id="max" value="<?= esc_attr( $field->max() ) ?>" />
Elasticsearch聚合
聚合的计算方式高度依赖于ES 查询上下文类型。对于过滤器(过滤器上下文),聚合是在整个索引的 所有 文档上计算的。这通常不是你想要构建分面过滤器搜索的情况。但是,为了将聚合的计算限制在匹配过滤器标准的文档子集上,你应该使用查询上下文。
示例
{
"filter": [
{
"term": {
"post_status": "publish"
}
}
],
"aggregations": {
"category": {
"terms": {
"field": "term.category.term_id"
}
}
}
}
上面的查询将计算完整索引的术语聚合(每个术语ID的文档数量),而不仅仅是已发布的文档。
要限制聚合到匹配的文档,你需要使用查询上下文
{
"query": {
"filtered": {
"filter": [
{
"term": {
"post_status": "publish"
}
}
]
}
},
"aggregations": {
"category": {
"terms": {
"field": "term.category.term_id"
}
}
}
}
弹性搜索将WP_Query参数映射到ES查询,有时使用过滤器上下文。如果您想在这些查询上构建聚合,必须将这些过滤器上下文转换为过滤查询
add_filter( 'ep_formatted_args', function( array $es_query, array $wp_query_args ) { if ( empty( $es_query[ 'aggs' ] ) || empty( $es_query[ 'filter' ] ) ) { return $es_query; //Don't touch queries that don't aggregate or has no filter } $es_query[ 'query' ] = [ 'filtered' => [ 'query' => $es_query[ 'query' ], 'filter' => $es_query[ 'filter' ] ] ]; unset( $es_query[ 'filter' ] ); return $es_query; }, 20, 2 }
域名语言
聚合字段
ElasticFacets\AggregationFields\*
聚合字段是某种类型对象,它根据ES索引(在本例中由弹性搜索提供)提供字段名称,以及用于识别查询中单个聚合的唯一ID。它们进一步提供任何信息,用于构建和解析特定类型的聚合,甚至验证请求参数。
SingleAggregationField
被认为用于仅关注文档单个字段的聚合。NumericRangeAggregationField
被认为用于单个字段的数值范围(之间)。
类型
类型对象提供聚合结果和其他数据结构。例如,NumericRange
类型提供min()
和max()
方法。一个Term
通过id()
和name()
定义。
查询
构建查询的对象,遵循ES DSL进行聚合。
结果
与Query
的对应:这些对象负责将ES结果解析为可用的值对象。(例如,术语集合,数值范围)
聚合
实现查询和结果接口的实现者。构建遵循ES DSL的查询并解析ES响应。
AbsoluteNumericRange
聚合数值字段的min/max值。(ES Min/Max聚合)ArbitraryNumericRange
聚合范围(计数给定范围内的文档)(ES Range聚合)SingleFieldTerms
聚合术语。(ES Term聚合)
测试
为了运行测试,您需要在系统上全局安装PHPUnit,或者使用PhiVE安装它
$ phive install
要运行单元测试,请使用此命令
$ bin/phpunit
(或全局安装时$ phpunit
)
代码覆盖率报告存储在tests/coverage.log
中。
变异测试
如果您已经在系统上安装了humbug(目前PhiVE不支持),您可以像这样运行它
$ humbug
它将分析src/
中的所有文件,并在tests/humbug.log
中创建报告。
由Inpsyde制作
Inpsyde团队自2006年以来一直在进行网络工程。
许可
版权(c)2016 David Naber,Inpsyde
好消息,这个插件对每个人都是免费的!由于它是在这个许可下发布的,您可以在个人或商业网站上免费使用它。
贡献
欢迎所有反馈/错误报告/拉取请求。