From 3c77ff074d631c5239d9eea6416c9fc1f08018ae Mon Sep 17 00:00:00 2001 From: Stefan Bofirov <stefan.bofirov@dnhsoft.com> Date: Mon, 1 Feb 2016 21:55:52 +0200 Subject: [PATCH] Implemented suggest support --- src/Search.php | 26 +++++++ src/SearchEndpoint/SearchEndpointFactory.php | 1 + src/SearchEndpoint/SuggestEndpoint.php | 42 ++++++++++ src/Suggest/Suggest.php | 82 ++++++++++++++++++++ tests/SearchEndpoint/SuggestEndpointTest.php | 65 ++++++++++++++++ tests/SearchTest.php | 31 ++++++++ tests/Suggest/SuggestTest.php | 69 ++++++++++++++++ 7 files changed, 316 insertions(+) create mode 100644 src/SearchEndpoint/SuggestEndpoint.php create mode 100644 src/Suggest/Suggest.php create mode 100644 tests/SearchEndpoint/SuggestEndpointTest.php create mode 100644 tests/Suggest/SuggestTest.php diff --git a/src/Search.php b/src/Search.php index 931f38b..0a524d9 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 b6352d1..291a631 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 0000000..9b35f7d --- /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; + } +} \ No newline at end of file diff --git a/src/Suggest/Suggest.php b/src/Suggest/Suggest.php new file mode 100644 index 0000000..411a973 --- /dev/null +++ b/src/Suggest/Suggest.php @@ -0,0 +1,82 @@ +<?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; + +class Suggest implements BuilderInterface +{ + const DEFAULT_SIZE = 3; + + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $text; + + /** + * @var array + */ + private $params; + + public function __construct($name, $text, $params = []) + { + $this->name = $name; + $this->text = $text; + $this->params = $params; + } + + /** + * 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 (!isset($this->params['field'])) { + $this->params['field'] = '_all'; + } + + if (!isset($this->params['size'])) { + $this->params['size'] = self::DEFAULT_SIZE; + } + + $output = [ + 'text' => $this->text, + 'term' => $this->params, + ]; + + return $output; + } +} \ No newline at end of file diff --git a/tests/SearchEndpoint/SuggestEndpointTest.php b/tests/SearchEndpoint/SuggestEndpointTest.php new file mode 100644 index 0000000..c1760b8 --- /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 17bebd5..fe438aa 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 0000000..a680f47 --- /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()); + } +} -- GitLab