Commit 3fb68096 by Carsten Brandt

add aggregation, stats and suggester to elasticsearch

fixes #4452, close #4452
parent 9dfca990
...@@ -11,6 +11,9 @@ Yii Framework 2 elasticsearch extension Change Log ...@@ -11,6 +11,9 @@ Yii Framework 2 elasticsearch extension Change Log
- Enh #4048: Added `init` event to `ActiveQuery` classes (qiangxue) - Enh #4048: Added `init` event to `ActiveQuery` classes (qiangxue)
- Enh #4086: changedAttributes of afterSave Event now contain old values (dizews) - Enh #4086: changedAttributes of afterSave Event now contain old values (dizews)
- Enh: Make error messages more readable in HTML output (cebe) - Enh: Make error messages more readable in HTML output (cebe)
- Enh: Added support for query stats (cebe)
- Enh: Added support for query suggesters (cebe)
- Chg #4451: Removed support for facets and replaced them with aggregations (cebe, tadaszelvys)
- Chg: asArray in ActiveQuery is now equal to using the normal Query. This means, that the output structure has changed and `with` is supported anymore. (cebe) - Chg: asArray in ActiveQuery is now equal to using the normal Query. This means, that the output structure has changed and `with` is supported anymore. (cebe)
- Chg: Deletion of a record is now also considered successful if the record did not exist. (cebe) - Chg: Deletion of a record is now also considered successful if the record did not exist. (cebe)
- Chg: Requirement changes: Yii now requires elasticsearch version 1.0 or higher (cebe) - Chg: Requirement changes: Yii now requires elasticsearch version 1.0 or higher (cebe)
......
...@@ -135,11 +135,29 @@ class Query extends Component implements QueryInterface ...@@ -135,11 +135,29 @@ class Query extends Component implements QueryInterface
/** /**
* @var array The highlight part of this search query. This is an array that allows to highlight search results * @var array The highlight part of this search query. This is an array that allows to highlight search results
* on one or more fields. * on one or more fields.
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-request-highlighting.html
*/ */
public $highlight; public $highlight;
public $facets = []; /**
* @var array List of aggregations to add to this query.
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-aggregations.html
*/
public $aggregations = [];
/**
* @var array the 'stats' part of the query. An array of groups to maintain a statistics aggregation for.
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search.html#stats-groups
*/
public $stats = [];
/**
* @var array list of suggesters to add to this query.
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters.html
*/
public $suggest = [];
/**
* @inheritdoc
*/
public function init() public function init()
{ {
parent::init(); parent::init();
...@@ -244,8 +262,6 @@ class Query extends Component implements QueryInterface ...@@ -244,8 +262,6 @@ class Query extends Component implements QueryInterface
return $result; return $result;
} }
// TODO add query stats http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search.html#stats-groups
// TODO add scroll/scan http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-search-type.html#scan // TODO add scroll/scan http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-search-type.html#scan
/** /**
...@@ -342,137 +358,72 @@ class Query extends Component implements QueryInterface ...@@ -342,137 +358,72 @@ class Query extends Component implements QueryInterface
} }
/** /**
* Adds a facet search to this query. * Adds a 'stats' part to the query.
* @param string $name the name of this facet * @param array $groups an array of groups to maintain a statistics aggregation for.
* @param string $type the facet type. e.g. `terms`, `range`, `histogram`...
* @param string|array $options the configuration options for this facet. Can be an array or a json string.
* @return static the query object itself * @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-query-facet.html * @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search.html#stats-groups
*/ */
public function addFacet($name, $type, $options) public function stats($groups)
{ {
$this->facets[$name] = [$type => $options]; $this->stats = $groups;
return $this; return $this;
} }
/** /**
* The `terms facet` allow to specify field facets that return the N most frequent terms. * Sets a highlight parameters to retrieve from the documents.
* @param string $name the name of this facet * @param array $highlight array of parameters to highlight results.
* @param array $options additional option. Please refer to the elasticsearch documentation for details.
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-facet.html
*/
public function addTermFacet($name, $options)
{
return $this->addFacet($name, 'terms', $options);
}
/**
* Range facet allows to specify a set of ranges and get both the number of docs (count) that fall
* within each range, and aggregated data either based on the field, or using another field.
* @param string $name the name of this facet
* @param array $options additional option. Please refer to the elasticsearch documentation for details.
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-range-facet.html
*/
public function addRangeFacet($name, $options)
{
return $this->addFacet($name, 'range', $options);
}
/**
* The histogram facet works with numeric data by building a histogram across intervals of the field values.
* Each value is "rounded" into an interval (or placed in a bucket), and statistics are provided per
* interval/bucket (count and total).
* @param string $name the name of this facet
* @param array $options additional option. Please refer to the elasticsearch documentation for details.
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-histogram-facet.html
*/
public function addHistogramFacet($name, $options)
{
return $this->addFacet($name, 'histogram', $options);
}
/**
* A specific histogram facet that can work with date field types enhancing it over the regular histogram facet.
* @param string $name the name of this facet
* @param array $options additional option. Please refer to the elasticsearch documentation for details.
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-date-histogram-facet.html
*/
public function addDateHistogramFacet($name, $options)
{
return $this->addFacet($name, 'date_histogram', $options);
}
/**
* A filter facet (not to be confused with a facet filter) allows you to return a count of the hits matching the filter.
* The filter itself can be expressed using the Query DSL.
* @param string $name the name of this facet
* @param string $filter the query in Query DSL
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-filter-facet.html
*/
public function addFilterFacet($name, $filter)
{
return $this->addFacet($name, 'filter', $filter);
}
/**
* A facet query allows to return a count of the hits matching the facet query.
* The query itself can be expressed using the Query DSL.
* @param string $name the name of this facet
* @param string $query the query in Query DSL
* @return static the query object itself * @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-query-facet.html * @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html
*/ */
public function addQueryFacet($name, $query) public function highlight($highlight)
{ {
return $this->addFacet($name, 'query', $query); $this->highlight = $highlight;
return $this;
} }
/** /**
* Statistical facet allows to compute statistical data on a numeric fields. The statistical data include count, * Adds an aggregation to this query.
* total, sum of squares, mean (average), minimum, maximum, variance, and standard deviation. * @param string $name the name of the aggregation
* @param string $name the name of this facet * @param string $type the aggregation type. e.g. `terms`, `range`, `histogram`...
* @param array $options additional option. Please refer to the elasticsearch documentation for details. * @param string|array $options the configuration options for this aggregation. Can be an array or a json string.
* @return static the query object itself * @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-statistical-facet.html * @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-aggregations.html
*/ */
public function addStatisticalFacet($name, $options) public function addAggregation($name, $type, $options)
{ {
return $this->addFacet($name, 'statistical', $options); $this->aggregations[$name] = [$type => $options];
return $this;
} }
/** /**
* The `terms_stats` facet combines both the terms and statistical allowing to compute stats computed on a field, * Adds an aggregation to this query.
* per term value driven by another field. *
* @param string $name the name of this facet * This is an alias for [[addAggregation]].
* @param array $options additional option. Please refer to the elasticsearch documentation for details. *
* @param string $name the name of the aggregation
* @param string $type the aggregation type. e.g. `terms`, `range`, `histogram`...
* @param string|array $options the configuration options for this aggregation. Can be an array or a json string.
* @return static the query object itself * @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-stats-facet.html * @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/search-aggregations.html
*/ */
public function addTermsStatsFacet($name, $options) public function addAgg($name, $type, $options)
{ {
return $this->addFacet($name, 'terms_stats', $options); return $this->addAggregation($name, $type, $options);
} }
/** /**
* The `geo_distance` facet is a facet providing information for ranges of distances from a provided `geo_point` * Adds a suggester to this query.
* including count of the number of hits that fall within each range, and aggregation information (like `total`). * @param string $name the name of the suggester
* @param string $name the name of this facet * @param string|array $definition the configuration options for this suggester. Can be an array or a json string.
* @param array $options additional option. Please refer to the elasticsearch documentation for details.
* @return static the query object itself * @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-geo-distance-facet.html * @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters.html
*/ */
public function addGeoDistanceFacet($name, $options) public function addSuggester($name, $definition)
{ {
return $this->addFacet($name, 'geo_distance', $options); $this->suggest[$name] = $definition;
return $this;
} }
// TODO add suggesters http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters.html
// TODO add validate query http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-validate.html // TODO add validate query http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-validate.html
// TODO support multi query via static method http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-multi-search.html // TODO support multi query via static method http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-multi-search.html
...@@ -532,18 +483,6 @@ class Query extends Component implements QueryInterface ...@@ -532,18 +483,6 @@ class Query extends Component implements QueryInterface
} }
/** /**
* Sets a highlight parameters to retrieve from the documents.
* @param array $highlight array of parameters to highlight results.
* @return static the query object itself
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html
*/
public function highlight($highlight)
{
$this->highlight = $highlight;
return $this;
}
/**
* Sets the source filtering, specifying how the `_source` field of the document should be returned. * Sets the source filtering, specifying how the `_source` field of the document should be returned.
* @param array $source the source patterns to be selected. * @param array $source the source patterns to be selected.
* @return static the query object itself * @return static the query object itself
......
...@@ -98,19 +98,24 @@ class QueryBuilder extends \yii\base\Object ...@@ -98,19 +98,24 @@ class QueryBuilder extends \yii\base\Object
$parts['filter'] = $whereFilter; $parts['filter'] = $whereFilter;
} }
if($query->highlight) { if (!empty($query->highlight)) {
$parts['highlight'] = $query->highlight; $parts['highlight'] = $query->highlight;
} }
if (!empty($query->aggregations)) {
$parts['aggregations'] = $query->aggregations;
}
if (!empty($query->stats)) {
$parts['stats'] = $query->stats;
}
if (!empty($query->suggest)) {
$parts['suggest'] = $query->suggest;
}
$sort = $this->buildOrderBy($query->orderBy); $sort = $this->buildOrderBy($query->orderBy);
if (!empty($sort)) { if (!empty($sort)) {
$parts['sort'] = $sort; $parts['sort'] = $sort;
} }
if (!empty($query->facets)) {
$parts['facets'] = $query->facets;
}
$options = []; $options = [];
if ($query->timeout !== null) { if ($query->timeout !== null) {
$options['timeout'] = $query->timeout; $options['timeout'] = $query->timeout;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment