Skip to content
Permalink
Browse files

Field Collapsing Support (#1653)

Added support for Field Collapsing as requested in #1392.
ES documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-collapse

Note: Inheriting `Query\InnerHits` in `Collapse\InnerHits` was something I've been debating with myself over and over again. As far as I'm concerned it makes sense to have different classes, especially as the collapse one has to have support for the second level collapse, but I didn't want to duplicate the entire code for InnerHits.
Downside is that right now there's no `AbstractCollapse` base-class as there is for the other concepts. Still feel like that's okay, because field collapsing is a quite simple concept right now.
  • Loading branch information
wackerl91 authored and ruflin committed Aug 22, 2019
1 parent c263181 commit 37822e64dddc1b3495a135f7584d091f161173ac
@@ -28,6 +28,7 @@ All notable changes to this project will be documented in this file based on the
* Elastica\Reindex missing options (script, remote, wait_for_completion, scroll...)
* Added `AdjacencyMatrix` aggregation [#1642](https://github.com/ruflin/Elastica/pull/1642)
* Added request method parameter to `Elastica\SearchableInterface->search()` and `Elastica\SearchableInterface->count()`. Same for `Elastica\Search`[#1441](https://github.com/ruflin/Elastica/issues/1441)
* Added support for Field Collapsing (Issue: [#1392](https://github.com/ruflin/Elastica/issues/1392); PR: [#1653](https://github.com/ruflin/Elastica/pull/1653))

### Improvements
* Added `native_function_invocation` CS rule [#1606](https://github.com/ruflin/Elastica/pull/1606)
@@ -0,0 +1,83 @@
<?php
namespace Elastica;
use Elastica\Collapse\InnerHits;
/**
* Class Collapse.
*
* Implementation of Collapse
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-collapse.html
*/
class Collapse extends Param
{
/**
* Set field to collapse.
*
* @param $fieldName
*
* @return $this
*/
public function setFieldname($fieldName): self
{
return $this->setParam('field', $fieldName);
}
/**
* Set inner hits for collapsed field.
*
* @param InnerHits $innerHits
*
* @return $this
*/
public function setInnerHits(InnerHits $innerHits): self
{
return $this->setParam('inner_hits', $innerHits);
}
/**
* @param InnerHits $innerHits
*
* @return Collapse
*/
public function addInnerHits(InnerHits $innerHits): self
{
$hits = [];
if ($this->hasParam('inner_hits')) {
$existingInnerHits = $this->getParam('inner_hits');
$hits = $existingInnerHits instanceof InnerHits ? [$existingInnerHits] : $existingInnerHits;
}
$hits[] = $innerHits;
return $this->setParam('inner_hits', $hits);
}
/**
* @param int $groupSearches
*
* @return $this
*/
public function setMaxConcurrentGroupSearches(int $groupSearches): self
{
return $this->setParam('max_concurrent_group_searches', $groupSearches);
}
/**
* @return array
*/
public function toArray(): array
{
$data = $this->getParams();
if (!empty($this->_rawParams)) {
$data = \array_merge($data, $this->_rawParams);
}
return $this->_convertArrayable($data);
}
}
@@ -0,0 +1,31 @@
<?php
namespace Elastica\Collapse;
use Elastica\Collapse;
use Elastica\Query\InnerHits as BaseInnerHits;
/**
* Class InnerHits.
*
* Basically identical to inner_hits on query level, but has support for a second level collapse as per
* https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#_second_level_of_collapsing
*
* Collapse is part of the inner_hits construct in this case, which should be explicitly supported and not only
* via calling InnerHits::setParam('collapse', $collapse).
*
* On the other hand, collapse cannot be used on query level invocations of inner_hits, which is why it may not be part
* of Query\InnerHits.
*/
class InnerHits extends BaseInnerHits
{
/**
* @param Collapse $collapse
*
* @return $this
*/
public function setCollapse(Collapse $collapse): self
{
return $this->setParam('collapse', $collapse);
}
}
@@ -42,6 +42,8 @@ public function __construct($query = null)
$this->setQuery($query);
} elseif ($query instanceof Suggest) {
$this->setSuggest($query);
} elseif ($query instanceof Collapse) {
$this->setCollapse($query);
}
}
@@ -74,6 +76,9 @@ public static function create($query)
case $query instanceof Suggest:
return new self($query);
case $query instanceof Collapse:
return new self($query);
}
throw new InvalidException('Unexpected argument to create a query for.');
@@ -108,7 +113,7 @@ public function setQuery(AbstractQuery $query)
/**
* Gets the query object.
*
* @return \Elastica\Query\AbstractQuery
* @return array|\Elastica\Query\AbstractQuery
**/
public function getQuery()
{
@@ -165,7 +170,7 @@ public function addSort($sort)
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_track_scores
*/
public function setTrackScores($trackScores = true)
public function setTrackScores($trackScores = true): self
{
return $this->setParam('track_scores', (bool) $trackScores);
}
@@ -426,4 +431,14 @@ public function setPostFilter(AbstractQuery $filter)
{
return $this->setParam('post_filter', $filter);
}
/**
* @param Collapse $collapse
*
* @return $this
*/
public function setCollapse(Collapse $collapse): self
{
return $this->setParam('collapse', $collapse);
}
}
@@ -12,6 +12,7 @@ interface DSL
const TYPE_QUERY = 'query';
const TYPE_AGGREGATION = 'aggregation';
const TYPE_SUGGEST = 'suggest';
const TYPE_COLLAPSE = 'collapse';
/**
* must return type for QueryBuilder usage.
@@ -0,0 +1,31 @@
<?php
namespace Elastica\QueryBuilder\DSL;
use Elastica\Query\InnerHits;
use Elastica\QueryBuilder\DSL;
/**
* Class Collapse.
*
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/6.7/search-request-collapse.html
*/
class Collapse implements DSL
{
/**
* @return string
*/
public function getType(): string
{
return self::TYPE_COLLAPSE;
}
/**
* @return InnerHits
*/
public function inner_hits(): InnerHits
{
return new InnerHits();
}
}

0 comments on commit 37822e6

Please sign in to comment.
You can’t perform that action at this time.