From ec4ea061364ce973944a086ddac33700eb27b719 Mon Sep 17 00:00:00 2001 From: Richard BAYET Date: Tue, 1 Oct 2024 17:28:25 +0200 Subject: [PATCH] [Core] Adding support for simple regexp queries --- .../Request/Query/Builder/Regexp.php | 56 +++++++++ .../Search/Request/Query/Regexp.php | 116 ++++++++++++++++++ .../Search/Request/QueryInterface.php | 1 + .../Request/Query/Builder/RegexpTest.php | 78 ++++++++++++ src/module-elasticsuite-core/etc/di.xml | 3 + 5 files changed, 254 insertions(+) create mode 100644 src/module-elasticsuite-core/Search/Adapter/Elasticsuite/Request/Query/Builder/Regexp.php create mode 100644 src/module-elasticsuite-core/Search/Request/Query/Regexp.php create mode 100644 src/module-elasticsuite-core/Test/Unit/Search/Adapter/Elasticsuite/Request/Query/Builder/RegexpTest.php diff --git a/src/module-elasticsuite-core/Search/Adapter/Elasticsuite/Request/Query/Builder/Regexp.php b/src/module-elasticsuite-core/Search/Adapter/Elasticsuite/Request/Query/Builder/Regexp.php new file mode 100644 index 000000000..82e4bebec --- /dev/null +++ b/src/module-elasticsuite-core/Search/Adapter/Elasticsuite/Request/Query/Builder/Regexp.php @@ -0,0 +1,56 @@ + + * @copyright 2024 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder; + +use Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\BuilderInterface; +use Smile\ElasticsuiteCore\Search\Request\QueryInterface; + +/** + * Build an ES regexp query. + * + * @category Smile + * @package Smile\ElasticsuiteCore + * @author Richard BAYET + */ +class Regexp implements BuilderInterface +{ + /** + * @var string + */ + const DEFAULT_FLAGS = 'NONE'; + + /** + * {@inheritDoc} + */ + public function buildQuery(QueryInterface $query) + { + if ($query->getType() !== QueryInterface::TYPE_REGEXP) { + throw new \InvalidArgumentException("Query builder : invalid query type {$query->getType()}"); + } + + $searchQueryParams = [ + 'value' => $query->getValue(), + 'boost' => $query->getBoost(), + 'flags' => self::DEFAULT_FLAGS, + ]; + + $searchQuery = ['regexp' => [$query->getField() => $searchQueryParams]]; + + if ($query->getName()) { + $searchQuery['regexp']['_name'] = $query->getName(); + } + + return $searchQuery; + } +} diff --git a/src/module-elasticsuite-core/Search/Request/Query/Regexp.php b/src/module-elasticsuite-core/Search/Request/Query/Regexp.php new file mode 100644 index 000000000..99c5974b2 --- /dev/null +++ b/src/module-elasticsuite-core/Search/Request/Query/Regexp.php @@ -0,0 +1,116 @@ + + * @copyright 2024 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteCore\Search\Request\Query; + +use Smile\ElasticsuiteCore\Search\Request\QueryInterface; + +/** + * ElasticSuite minimal regexp query implementation. + * + * @category Smile + * @package Smile\ElasticsuiteCore + * @author Richard BAYET + */ +class Regexp implements QueryInterface +{ + /** + * @var string + */ + private $name; + + /** + * @var integer + */ + private $boost; + + /** + * @var string + */ + private $value; + + /** + * @var string + */ + private $field; + + /** + * Constructor. + * + * @param string $value Query value ie the regular expression. + * @param string $field Query field. + * @param string $name Name of the query. + * @param integer $boost Query boost. + */ + public function __construct($value, $field, $name = null, $boost = QueryInterface::DEFAULT_BOOST_VALUE) + { + $this->name = $name; + $this->value = $value; + $this->field = $field; + $this->boost = $boost; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritDoc} + */ + public function setName($name): self + { + $this->name = $name; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function getBoost() + { + return $this->boost; + } + + /** + * {@inheritDoc} + */ + public function getType() + { + return QueryInterface::TYPE_REGEXP; + } + + /** + * Search value. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Search field. + * + * @return string + */ + public function getField() + { + return $this->field; + } +} diff --git a/src/module-elasticsuite-core/Search/Request/QueryInterface.php b/src/module-elasticsuite-core/Search/Request/QueryInterface.php index df176bcf9..92c2ccd8a 100644 --- a/src/module-elasticsuite-core/Search/Request/QueryInterface.php +++ b/src/module-elasticsuite-core/Search/Request/QueryInterface.php @@ -38,6 +38,7 @@ interface QueryInterface extends \Magento\Framework\Search\Request\QueryInterfac const TYPE_MORELIKETHIS = 'moreLikeThisQuery'; const TYPE_MATCHPHRASEPREFIX = 'matchPhrasePrefixQuery'; const TYPE_PREFIX = 'prefixQuery'; + const TYPE_REGEXP = 'regexpQuery'; /** * Set the query name diff --git a/src/module-elasticsuite-core/Test/Unit/Search/Adapter/Elasticsuite/Request/Query/Builder/RegexpTest.php b/src/module-elasticsuite-core/Test/Unit/Search/Adapter/Elasticsuite/Request/Query/Builder/RegexpTest.php new file mode 100644 index 000000000..432205b0f --- /dev/null +++ b/src/module-elasticsuite-core/Test/Unit/Search/Adapter/Elasticsuite/Request/Query/Builder/RegexpTest.php @@ -0,0 +1,78 @@ + + * @copyright 2024 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteCore\Test\Unit\Search\Adapter\Elasticsuite\Request\Query\Builder; + +use Smile\ElasticsuiteCore\Search\Request\Query\Regexp as RegexpQuery; +use Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder\Regexp as RegexpQueryBuilder; + +/** + * Regexp search query test case. + * + * @category Smile + * @package Smile\ElasticsuiteCore + * @author Richard BAYET + */ +class RegexpTest extends AbstractSimpleQueryBuilderTest +{ + /** + * Test the builder with mandatory params only. + * + * @return void + */ + public function testAnonymousRegexpQueryBuilder() + { + $builder = $this->getQueryBuilder(); + + $regexpQuery = new RegexpQuery('value', 'field'); + $query = $builder->buildQuery($regexpQuery); + + $this->assertArrayHasKey('regexp', $query); + $this->assertArrayHasKey('field', $query['regexp']); + $this->assertArrayHasKey('value', $query['regexp']['field']); + $this->assertEquals('value', $query['regexp']['field']['value']); + + $this->assertArrayHasKey('boost', $query['regexp']['field']); + $this->assertEquals(RegexpQuery::DEFAULT_BOOST_VALUE, $query['regexp']['field']['boost']); + + $this->assertArrayHasKey('flags', $query['regexp']['field']); + $this->assertEquals($builder::DEFAULT_FLAGS, $query['regexp']['field']['boost']); + + $this->assertArrayNotHasKey('_name', $query['regexp']); + } + + /** + * Test the builder with mandatory + name params. + * + * @return void + */ + public function testNamedRegexpQueryBuilder() + { + $builder = $this->getQueryBuilder(); + + $regexpQuery = new RegexpQuery('value', 'field', 'queryName'); + $query = $builder->buildQuery($regexpQuery); + + $this->assertArrayHasKey('regexp', $query); + $this->assertArrayHasKey('_name', $query['regexp']); + $this->assertEquals('queryName', $query['regexp']['_name']); + } + + /** + * {@inheritDoc} + */ + protected function getQueryBuilder() + { + return new RegexpQueryBuilder(); + } +} diff --git a/src/module-elasticsuite-core/etc/di.xml b/src/module-elasticsuite-core/etc/di.xml index 4fbbe3f69..bf9fd4bfe 100644 --- a/src/module-elasticsuite-core/etc/di.xml +++ b/src/module-elasticsuite-core/etc/di.xml @@ -122,6 +122,7 @@ spanTermFactory spanWithinFactory prefixQueryFactory + regexpQueryFactory @@ -151,6 +152,7 @@ + @@ -180,6 +182,7 @@ Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder\Span\SpanTerm\Proxy Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder\Span\SpanWithin\Proxy Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder\Prefix\Proxy + Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder\Regexp\Proxy