diff --git a/src/Search.php b/src/Search.php index 931f38b36ae627dd6a3e6e450ea4f46c5d5def64..0a524d918398056b1d98d58be20412938ba897ee 100644 --- a/src/Search.php +++ b/src/Search.php @@ -26,6 +26,8 @@ use ONGR\ElasticsearchDSL\SearchEndpoint\SortEndpoint; use ONGR\ElasticsearchDSL\Serializer\Normalizer\CustomReferencedNormalizer; use ONGR\ElasticsearchDSL\Serializer\OrderedSerializer; use Symfony\Component\Serializer\Normalizer\CustomNormalizer; +use ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint; +use ONGR\ElasticsearchDSL\Suggest\Suggest; /** * Search object that can be executed by a manager. @@ -378,6 +380,30 @@ class Search return $highlightEndpoint->getHighlight(); } + /** + * Adds suggest into search. + * + * @param Suggest $suggest + * + * @return $this + */ + public function addSuggest(Suggest $suggest) + { + $this->getEndpoint(SuggestEndpoint::NAME)->add($suggest, $suggest->getName()); + + return $this; + } + + /** + * Returns all suggests. + * + * @return BuilderInterface[] + */ + public function getSuggests() + { + return $this->getEndpoint(SuggestEndpoint::NAME)->getAll(); + } + /** * Exclude documents which have a _score less than the minimum specified. * diff --git a/src/SearchEndpoint/SearchEndpointFactory.php b/src/SearchEndpoint/SearchEndpointFactory.php index b6352d19e2f6f2480fe0bc06f5adea2f1b0efa5d..291a631479b5f94eba66a6a4f6cda191e1348622 100644 --- a/src/SearchEndpoint/SearchEndpointFactory.php +++ b/src/SearchEndpoint/SearchEndpointFactory.php @@ -26,6 +26,7 @@ class SearchEndpointFactory 'sort' => 'ONGR\ElasticsearchDSL\SearchEndpoint\SortEndpoint', 'highlight' => 'ONGR\ElasticsearchDSL\SearchEndpoint\HighlightEndpoint', 'aggregations' => 'ONGR\ElasticsearchDSL\SearchEndpoint\AggregationsEndpoint', + 'suggest' => 'ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint', ]; /** diff --git a/src/SearchEndpoint/SuggestEndpoint.php b/src/SearchEndpoint/SuggestEndpoint.php new file mode 100644 index 0000000000000000000000000000000000000000..323bd2280f29c42fb0459582e788c156db2cb707 --- /dev/null +++ b/src/SearchEndpoint/SuggestEndpoint.php @@ -0,0 +1,42 @@ +<?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\Suggest\Suggest; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; + +/** + * Search suggest dsl endpoint. + */ +class SuggestEndpoint extends AbstractSearchEndpoint +{ + /** + * Endpoint name + */ + const NAME = 'suggest'; + + /** + * {@inheritdoc} + */ + public function normalize(NormalizerInterface $normalizer, $format = null, array $context = []) + { + $output = []; + if (count($this->getAll()) > 0) { + /** @var Suggest $suggest */ + foreach ($this->getAll() as $suggest) { + $output[$suggest->getName()] = $suggest->toArray(); + } + } + + return $output; + } +} diff --git a/src/Suggest/Suggest.php b/src/Suggest/Suggest.php new file mode 100644 index 0000000000000000000000000000000000000000..fe70fb947e0ea931a273c58f6e94166058b06c32 --- /dev/null +++ b/src/Suggest/Suggest.php @@ -0,0 +1,80 @@ +<?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\Suggest; + +use ONGR\ElasticsearchDSL\BuilderInterface; +use ONGR\ElasticsearchDSL\ParametersTrait; + +class Suggest implements BuilderInterface +{ + use ParametersTrait; + + const DEFAULT_SIZE = 3; + + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $text; + + public function __construct($name, $text, $parameters = []) + { + $this->name = $name; + $this->text = $text; + $this->setParameters($parameters); + } + + /** + * Returns element type. + * + * @return string + */ + public function getType() + { + return 'suggest'; + } + + /** + * Returns suggest name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function toArray() + { + if (!$this->hasParameter('field')) { + $this->addParameter('field', '_all'); + } + + if (!$this->hasParameter('size')) { + $this->addParameter('size', self::DEFAULT_SIZE); + } + + $output = [ + 'text' => $this->text, + 'term' => $this->getParameters(), + ]; + + return $output; + } +} diff --git a/tests/SearchEndpoint/SuggestEndpointTest.php b/tests/SearchEndpoint/SuggestEndpointTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c1760b80e1a32e236e8046aff55b77fa497fe3c0 --- /dev/null +++ b/tests/SearchEndpoint/SuggestEndpointTest.php @@ -0,0 +1,65 @@ +<?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\Tests\Unit\SearchEndpoint; + +use ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint; +use ONGR\ElasticsearchDSL\Suggest\Suggest; +use PHPUnit_Framework_MockObject_MockObject as MockObject; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; + +class SuggestEndpointTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests constructor. + */ + public function testItCanBeInstantiated() + { + $this->assertInstanceOf('ONGR\ElasticsearchDSL\SearchEndpoint\SuggestEndpoint', new SuggestEndpoint()); + } + + /** + * Tests if endpoint returns builders. + */ + public function testEndpointGetter() + { + $suggestName = 'acme_suggest'; + $text = 'foo'; + $suggest = new Suggest($suggestName, $text); + $endpoint = new SuggestEndpoint(); + $endpoint->add($suggest, $suggestName); + $builders = $endpoint->getAll(); + + $this->assertCount(1, $builders); + $this->assertSame($suggest, $builders[$suggestName]); + } + + /** + * Tests endpoint normalization. + */ + public function testNormalize() + { + $instance = new SuggestEndpoint(); + + /** @var NormalizerInterface|MockObject $normalizerInterface */ + $normalizerInterface = $this->getMockForAbstractClass( + 'Symfony\Component\Serializer\Normalizer\NormalizerInterface' + ); + + $suggest = new Suggest('foo', 'bar'); + $instance->add($suggest); + + $this->assertEquals( + ['foo' => $suggest->toArray()], + $instance->normalize($normalizerInterface) + ); + } +} diff --git a/tests/SearchTest.php b/tests/SearchTest.php index 17bebd58e5cbf30775462ba6e28c914022a165a3..fe438aa42f91c9449e18a5cd688aabc18f8abfc2 100644 --- a/tests/SearchTest.php +++ b/tests/SearchTest.php @@ -15,6 +15,7 @@ use ONGR\ElasticsearchDSL\Query\MissingQuery; use ONGR\ElasticsearchDSL\Query\TermQuery; use ONGR\ElasticsearchDSL\Search; use ONGR\ElasticsearchDSL\Sort\FieldSort; +use ONGR\ElasticsearchDSL\Suggest\Suggest; /** * Test for Search. @@ -256,6 +257,36 @@ class SearchTest extends \PHPUnit_Framework_TestCase (new Search())->addSort(new FieldSort('price', 'asc')), ]; + $cases['single_suggest'] = [ + [ + 'suggest' => [ + 'foo' => [ + 'text' => 'bar', + 'term' => ['field' => 'title', 'size' => 2], + ], + ], + ], + (new Search())->addSuggest(new Suggest('foo', 'bar', ['field' => 'title', 'size' => 2])), + ]; + + $cases['multiple_suggests'] = [ + [ + 'suggest' => [ + 'foo' => [ + 'text' => 'bar', + 'term' => ['field' => 'title', 'size' => 2], + ], + 'bar' => [ + 'text' => 'foo', + 'term' => ['field' => 'title', 'size' => 2], + ], + ], + ], + (new Search()) + ->addSuggest(new Suggest('foo', 'bar', ['field' => 'title', 'size' => 2])) + ->addSuggest(new Suggest('bar', 'foo', ['field' => 'title', 'size' => 2])), + ]; + return $cases; } diff --git a/tests/Suggest/SuggestTest.php b/tests/Suggest/SuggestTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a680f476b81dcf97462b5f772750dcb325ebf53a --- /dev/null +++ b/tests/Suggest/SuggestTest.php @@ -0,0 +1,69 @@ +<?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\Tests\Suggest; + +use ONGR\ElasticsearchDSL\Suggest\Suggest; + +class SuggestTest extends \PHPUnit_Framework_TestCase +{ + /** + * Tests getType method. + */ + public function testSuggestGetType() + { + $suggest = new Suggest('foo', 'bar'); + $result = $suggest->getType(); + $this->assertEquals('suggest', $result); + } + + /** + * Tests toArray() method. + */ + public function testSuggestWithoutFieldAndSize() + { + // Case #1 suggest without field and size params. + $suggest = new Suggest('foo', 'bar'); + $expected = [ + 'text' => 'bar', + 'term' => [ + 'field' => '_all', + 'size' => 3, + ], + ]; + $this->assertEquals($expected, $suggest->toArray()); + } + + /** + * Tests toArray() method. + */ + public function testToArray() + { + $suggest = new Suggest( + 'foo', + 'bar', + [ + 'size' => 5, + 'field' => 'title', + 'analyzer' => 'whitespace', + ] + ); + $expected = [ + 'text' => 'bar', + 'term' => [ + 'field' => 'title', + 'size' => 5, + 'analyzer' => 'whitespace', + ], + ]; + $this->assertEquals($expected, $suggest->toArray()); + } +}