diff --git a/src/SearchEndpoint/AbstractSearchEndpoint.php b/src/SearchEndpoint/AbstractSearchEndpoint.php index 0480223785811dfca8e47e66f20c8722906e71c0..d6bdc9662604c6eb16309df078de5db533ecbc87 100644 --- a/src/SearchEndpoint/AbstractSearchEndpoint.php +++ b/src/SearchEndpoint/AbstractSearchEndpoint.php @@ -11,6 +11,8 @@ namespace ONGR\ElasticsearchDSL\SearchEndpoint; +use ONGR\ElasticsearchDSL\BuilderInterface; +use ONGR\ElasticsearchDSL\ParametersTrait; use ONGR\ElasticsearchDSL\Serializer\Normalizer\AbstractNormalizable; /** @@ -18,5 +20,79 @@ use ONGR\ElasticsearchDSL\Serializer\Normalizer\AbstractNormalizable; */ abstract class AbstractSearchEndpoint extends AbstractNormalizable implements SearchEndpointInterface { - use BuilderContainerAwareTrait; + use ParametersTrait; + + /** + * @var BuilderInterface[] + */ + private $container = []; + + /** + * {@inheritdoc} + */ + public function add(BuilderInterface $builder, $key = null) + { + if (array_key_exists($key, $this->container)) { + throw new \OverflowException(sprintf('Builder with %s name for endpoint has already been added!', $key)); + } + + if (!$key) { + $key = uniqid(); + } + + $this->container[$key] = $builder; + + return $key; + } + + /** + * {@inheritdoc} + */ + public function addToBool(BuilderInterface $builder, $boolType = null, $key = null) + { + throw new \BadFunctionCallException(sprintf("Endpoint %s doesn't support bool statements", static::NAME)); + } + + /** + * {@inheritdoc} + */ + public function remove($key) + { + if ($this->has($key)) { + unset($this->container[$key]); + } + + return $this; + } + + /** + * Checks if builder with specific key exists. + * + * @param $key + * @return bool + */ + public function has($key) + { + return array_key_exists($key, $this->container); + } + + /** + * {@inheritdoc} + */ + public function get($key) + { + if ($this->has($key)) { + return $this->container[$key]; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function getAll($boolType = null) + { + return $this->container; + } } diff --git a/src/SearchEndpoint/AggregationsEndpoint.php b/src/SearchEndpoint/AggregationsEndpoint.php index e9f9ae7e7d8c0ab4ea75cc41b426c0c94d0b61e7..444066df949ed2ef3274a7611535cb175870fdf7 100644 --- a/src/SearchEndpoint/AggregationsEndpoint.php +++ b/src/SearchEndpoint/AggregationsEndpoint.php @@ -11,84 +11,31 @@ namespace ONGR\ElasticsearchDSL\SearchEndpoint; -use ONGR\ElasticsearchDSL\BuilderInterface; -use ONGR\ElasticsearchDSL\NamedBuilderBag; -use ONGR\ElasticsearchDSL\NamedBuilderInterface; +use ONGR\ElasticsearchDSL\BuilderBag; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * Search aggregations dsl endpoint. */ -class AggregationsEndpoint implements SearchEndpointInterface +class AggregationsEndpoint extends AbstractSearchEndpoint { - use BuilderContainerAwareTrait; - /** - * @var NamedBuilderBag + * Endpoint name */ - private $bag; - - /** - * Initialized aggregations bag. - */ - public function __construct() - { - $this->bag = new NamedBuilderBag(); - } + CONST NAME = 'aggregations'; /** * {@inheritdoc} */ public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { - if (count($this->bag->all()) > 0) { - return $this->bag->toArray(); - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function addBuilder(BuilderInterface $builder, $parameters = []) - { - if (!($builder instanceof NamedBuilderInterface)) { - throw new \InvalidArgumentException('Builder must be named builder'); - } - - $this->bag->add($builder); - - return $builder->getName(); - } - - /** - * {@inheritdoc} - */ - public function getBuilders() - { - return $this->bag->all(); - } - - /** - * {@inheritdoc} - */ - public function getBuilder($key) - { - if (!$this->bag->has($key)) { - return null; + if (count($this->getAll()) > 0) { + $output = []; + foreach ($this->getAll() as $aggregation) { + $output[] = $aggregation->toArray(); + } } - return $this->bag->get($key); - } - - /** - * {@inheritdoc} - */ - public function removeBuilder($key) - { - $this->bag->remove($key); - - return $this; + return $output; } } diff --git a/src/SearchEndpoint/BuilderContainerAwareTrait.php b/src/SearchEndpoint/BuilderContainerAwareTrait.php deleted file mode 100644 index d6b3aa6e7cd8c781e9e670c69fc401734e352189..0000000000000000000000000000000000000000 --- a/src/SearchEndpoint/BuilderContainerAwareTrait.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php - -/* - * This file is part of the ONGR package. - * - * (c) NFQ Technologies UAB <info@nfq.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace ONGR\ElasticsearchDSL\SearchEndpoint; - -use ONGR\ElasticsearchDSL\BuilderInterface; - -/** - * Trait to implement SearchEndpointInterface builder methods. - */ -trait BuilderContainerAwareTrait -{ - /** - * @var BuilderInterface[] - */ - private $builderContainer = []; - - /** - * @var array - */ - private $parameterContainer = []; - - /** - * {@inheritdoc} - */ - public function addBuilder(BuilderInterface $builder, $parameters = []) - { - $this->builderContainer[] = $builder; - end($this->builderContainer); - $key = key($this->builderContainer); - - $this->parameterContainer[$key] = $parameters; - - return $key; - } - - /** - * {@inheritdoc} - */ - public function removeBuilder($key) - { - if (array_key_exists($key, $this->builderContainer)) { - unset($this->builderContainer[$key]); - unset($this->parameterContainer[$key]); - } - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getBuilder($key) - { - if (array_key_exists($key, $this->builderContainer)) { - return $this->builderContainer[$key]; - } - - return null; - } - - /** - * {@inheritdoc} - */ - public function getBuilders() - { - return $this->builderContainer; - } - - /** - * {@inheritdoc} - */ - public function getBuilderParameters($key) - { - if (array_key_exists($key, $this->parameterContainer)) { - return $this->parameterContainer[$key]; - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function setBuilderParameters($key, $parameters) - { - $this->parameterContainer[$key] = $parameters; - - return $this; - } -} diff --git a/src/SearchEndpoint/FilterEndpoint.php b/src/SearchEndpoint/FilterEndpoint.php index 1e375095c3156b80b1ebcb30b6b50fc1b5c2e070..ef53e00d82ee63dc9d75218c8e87adae1c78e0f9 100644 --- a/src/SearchEndpoint/FilterEndpoint.php +++ b/src/SearchEndpoint/FilterEndpoint.php @@ -20,18 +20,29 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; */ class FilterEndpoint extends QueryEndpoint { + /** + * Endpoint name + */ + CONST NAME = 'filter'; + /** * {@inheritdoc} */ public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { - $builder = $this->getBuilderForNormalization(); - if (empty($builder)) { - return; + if (!$this->getBool()) { + return null; } $query = new FilteredQuery(); - $query->setFilter($builder); + if ($this->getBool()->isRelevant()) { + $filters = $this->getBool()->getQueries(BoolFilter::MUST); + $filter = array_shift($filters); + } else { + $filter = $this->getBool(); + } + + $query->setFilter($filter); $this->addReference('filtered_query', $query); } @@ -44,7 +55,9 @@ class FilterEndpoint extends QueryEndpoint } /** - * {@inheritdoc} + * Returns bool instance for this endpoint case. + * + * @return BoolFilter */ protected function getBoolInstance() { diff --git a/src/SearchEndpoint/HighlightEndpoint.php b/src/SearchEndpoint/HighlightEndpoint.php index ddc61199a2449ce3b67d7e81f2ae7d9520c16e2c..c0d16a584f3b7ef7570c9daacdb7c9267ea52156 100644 --- a/src/SearchEndpoint/HighlightEndpoint.php +++ b/src/SearchEndpoint/HighlightEndpoint.php @@ -17,14 +17,15 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * Search highlight dsl endpoint. */ -class HighlightEndpoint implements SearchEndpointInterface +class HighlightEndpoint extends AbstractSearchEndpoint { - use BuilderContainerAwareTrait { - addBuilder as private traitAddBuilder; - } + /** + * Endpoint name + */ + CONST NAME = 'highlight'; /** - * @var int + * @var BuilderInterface */ private $highlight; @@ -33,24 +34,22 @@ class HighlightEndpoint implements SearchEndpointInterface */ public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { - if (!$this->getBuilder($this->highlight)) { - return null; + if ($this->highlight) { + return $this->highlight->toArray(); } - return $this->getBuilder($this->highlight)->toArray(); + return null; } /** * {@inheritdoc} */ - public function addBuilder(BuilderInterface $builder, $parameters = []) + public function add(BuilderInterface $builder, $key = null) { - if ($this->getBuilders()) { - throw new \OverflowException('Only one highlight is expected'); + if ($this->highlight) { + throw new \OverflowException('Only one highlight can be set'); } - $this->highlight = $this->traitAddBuilder($builder, $parameters); - - return $this->highlight; + $this->highlight = $builder; } } diff --git a/src/SearchEndpoint/PostFilterEndpoint.php b/src/SearchEndpoint/PostFilterEndpoint.php index 50e2fb7b9f2e6bc7da24e76f1c51361b029b2a26..88bfc57f5c179d4365461a65ede2bdb52e88fd83 100644 --- a/src/SearchEndpoint/PostFilterEndpoint.php +++ b/src/SearchEndpoint/PostFilterEndpoint.php @@ -11,7 +11,7 @@ namespace ONGR\ElasticsearchDSL\SearchEndpoint; -use ONGR\ElasticsearchDSL\Filter\PostFilter; +use ONGR\ElasticsearchDSL\Filter\BoolFilter; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** @@ -19,20 +19,35 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; */ class PostFilterEndpoint extends FilterEndpoint { + /** + * Endpoint name + */ + CONST NAME = 'post_filter'; + /** * {@inheritdoc} */ public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { - $builder = $this->getBuilderForNormalization(); - - if (empty($builder)) { + if (!$this->getBool()) { return null; } - $postFilter = new PostFilter(); - $postFilter->setFilter($builder); + if ($this->getBool()->isRelevant()) { + $filters = $this->getBool()->getQueries(BoolFilter::MUST); + $filter = array_shift($filters); + } else { + $filter = $this->getBool(); + } - return $postFilter->toArray(); + return [$filter->getType() => $filter->toArray()]; + } + + /** + * {@inheritdoc} + */ + public function getOrder() + { + return 2; } } diff --git a/src/SearchEndpoint/QueryEndpoint.php b/src/SearchEndpoint/QueryEndpoint.php index b8d2da882e4b8882e3c5f6c394605d1e23d202d2..1c4c83e08d29222fb669281783c0406a1e232df6 100644 --- a/src/SearchEndpoint/QueryEndpoint.php +++ b/src/SearchEndpoint/QueryEndpoint.php @@ -25,21 +25,15 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; */ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerInterface { - use ParametersTrait; - /** - * @var OptionsResolver + * Endpoint name */ - private $resolver; + CONST NAME = 'query'; /** - * Instantiates resolver. + * @var BoolQuery */ - public function __construct() - { - $this->resolver = new OptionsResolver(); - $this->configureResolver($this->resolver); - } + private $bool; /** * {@inheritdoc} @@ -47,90 +41,67 @@ class QueryEndpoint extends AbstractSearchEndpoint implements OrderedNormalizerI public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { if ($this->hasReference('filtered_query')) { - /** @var FilteredQuery $query */ - $query = $this->getReference('filtered_query'); - $this->addBuilder($query); + /** @var FilteredQuery $filteredQuery */ + $filteredQuery = $this->getReference('filtered_query'); + $this->add($filteredQuery); } - $builder = $this->getBuilderForNormalization(); - - if (empty($builder)) { + if (!$this->bool) { return null; } - return [$builder->getType() => $builder->toArray()]; + $queryArray = $this->bool->toArray(); + + if (!$this->bool->isRelevant()) { + $queryArray = [$this->bool->getType() => $queryArray]; + } + + return $queryArray; } /** - * Return builder that is ready to be normalized. - * - * @return BuilderInterface|null + * {@inheritdoc} */ - protected function getBuilderForNormalization() + public function add(BuilderInterface $builder, $key = null) { - $builders = $this->getbuilders(); - if (empty($builders)) { - return null; - } - - if (count($builders) > 1) { - $builder = $this->buildBool(); - } else { - $builder = end($builders); - } - - if (method_exists($builder, 'setParameters') && count($this->getParameters()) > 0) { - $builder->setParameters($this->processArray($builder->getParameters())); - } - - return $builder; + return $this->addToBool($builder, BoolQuery::MUST, $key); } /** * {@inheritdoc} */ - public function getOrder() + public function addToBool(BuilderInterface $builder, $boolType = null, $key = null) { - return 2; + if (!$this->bool) { + $this->bool = $this->createBoolInstance(); + } + + $this->bool->add($builder, $boolType, $key); } /** - * Default properties for query. - * - * @param OptionsResolver $resolver + * {@inheritdoc} */ - protected function configureResolver(OptionsResolver $resolver) + public function getOrder() { - $resolver - ->setDefaults( - ['bool_type' => BoolQuery::MUST] - ); + return 3; } /** - * Returns bool instance for this endpoint case. - * - * @return BoolFilter|BoolQuery + * @return BoolQuery */ - protected function getBoolInstance() + public function getBool() { - return new BoolQuery(); + return $this->bool; } /** - * Returns bool instance with builders set. + * Returns new bool instance for the endpoint. * - * @return BoolFilter|BoolQuery + * @return BoolQuery */ - protected function buildBool() + protected function createBoolInstance() { - $boolInstance = $this->getBoolInstance(); - - foreach ($this->getBuilders() as $key => $builder) { - $parameters = $this->resolver->resolve(array_filter($this->getBuilderParameters($key))); - $boolInstance->add($builder, $parameters['bool_type']); - } - - return $boolInstance; + return new BoolQuery(); } } diff --git a/src/SearchEndpoint/SearchEndpointInterface.php b/src/SearchEndpoint/SearchEndpointInterface.php index 1f04cea444d92c2500751da47f9640dfa25c36b6..13991125fab1c4fda8c5b24a18809336b34fd9f4 100644 --- a/src/SearchEndpoint/SearchEndpointInterface.php +++ b/src/SearchEndpoint/SearchEndpointInterface.php @@ -12,6 +12,7 @@ namespace ONGR\ElasticsearchDSL\SearchEndpoint; use ONGR\ElasticsearchDSL\BuilderInterface; +use ONGR\ElasticsearchDSL\Query\BoolQuery; use Symfony\Component\Serializer\Normalizer\NormalizableInterface; /** @@ -23,11 +24,23 @@ interface SearchEndpointInterface extends NormalizableInterface * Adds builder to search endpoint. * * @param BuilderInterface $builder Builder to add. - * @param array $parameters Additional parameters relevant to builder. + * @param array $key Additional parameters relevant to builder. * - * @return int Returns builder key. + * @return string Key of added builder. */ - public function addBuilder(BuilderInterface $builder, $parameters = []); + public function add(BuilderInterface $builder, $key = null); + + /** + * Adds builder to search endpoint's specific bool type container. + * + * @param BuilderInterface $builder Builder to add. + * @param array $boolType Bool type for query or filter. If bool type is left null + * it will be treated as MUST. + * @param array $key Additional parameters relevant to builder. + * + * @return string Key of added builder. + */ + public function addToBool(BuilderInterface $builder, $boolType = null, $key = null); /** * Removes contained builder. @@ -36,7 +49,7 @@ interface SearchEndpointInterface extends NormalizableInterface * * @return $this */ - public function removeBuilder($key); + public function remove($key); /** * Returns contained builder or null if Builder is not found. @@ -45,29 +58,14 @@ interface SearchEndpointInterface extends NormalizableInterface * * @return BuilderInterface|null */ - public function getBuilder($key); + public function get($key); /** - * Returns all contained builders. - * - * @return BuilderInterface[] - */ - public function getBuilders(); - - /** - * Returns parameters for contained builder or empty array if parameters are not found. + * Returns contained builder or null if Builder is not found. * - * @param int $key + * @param string|null $boolType If bool type is left null it will return all builders from container. * * @return array */ - public function getBuilderParameters($key); - - /** - * @param int $key - * @param array $parameters - * - * @return $this - */ - public function setBuilderParameters($key, $parameters); + public function getAll($boolType = null); } diff --git a/src/SearchEndpoint/SortEndpoint.php b/src/SearchEndpoint/SortEndpoint.php index 7c14cc76c24cc6ff3507fa9c1142d888da47e4e6..13eaf6a828bbaa52dd6576bd3f950c6456b34546 100644 --- a/src/SearchEndpoint/SortEndpoint.php +++ b/src/SearchEndpoint/SortEndpoint.php @@ -19,51 +19,24 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; /** * Search sort dsl endpoint. */ -class SortEndpoint implements SearchEndpointInterface +class SortEndpoint extends AbstractSearchEndpoint { - use BuilderContainerAwareTrait { - addBuilder as private traitAddBuilder; - } - - /** - * {@inheritdoc} - */ - public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) - { - $sorts = $this->buildSorts(); - - if ($sorts->isRelevant()) { - return $sorts->toArray(); - } - - return null; - } - /** - * Builds sorts object. - * - * @return Sorts + * Endpoint name */ - protected function buildSorts() - { - $sorts = new Sorts(); - /** @var AbstractSort $builder */ - foreach ($this->getBuilders() as $builder) { - $sorts->addSort($builder); - } - - return $sorts; - } + CONST NAME = 'sort'; /** * {@inheritdoc} */ - public function addBuilder(BuilderInterface $builder, $parameters = []) + public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) { - if (!($builder instanceof AbstractSort)) { - throw new \InvalidArgumentException('Sort must must a subtype of AbstractSort'); + $output = []; + + foreach($this->getAll() as $sort) { + $output[] = $sort->toArray(); } - return $this->traitAddBuilder($builder, $parameters); + return $output; } }