inpsyde/elastic-facets

此包已被废弃,不再维护。未建议替代包。

提供API以访问Elasticsearch聚合,以构建分面搜索表单

安装量: 1,028

依赖项: 0

建议者: 0

安全: 0

星标: 11

关注者: 4

分支: 1

开放问题: 0

类型:wordpress-plugin

1.0.0-alpha3 2017-02-02 14:00 UTC

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_tagcategory)在默认搜索查询上的术语聚合。

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_colorpa_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

好消息,这个插件对每个人都是免费的!由于它是在这个许可下发布的,您可以在个人或商业网站上免费使用它。

贡献

欢迎所有反馈/错误报告/拉取请求。