From eb56967a7f866bdb857232553734823698c89008 Mon Sep 17 00:00:00 2001 From: Anvit Srivastav Date: Tue, 20 Aug 2024 14:12:33 -0700 Subject: [PATCH] Add terms query for solr Add arSolrTermsQuery and associated tests. Also fix typo in a property name in arSolrTermQuery. --- .../lib/query/arSolrTermQuery.class.php | 2 +- .../lib/query/arSolrTermsQuery.class.php | 130 ++++++++++++ .../lib/query/ArSolrTermsQueryTest.php | 199 ++++++++++++++++++ 3 files changed, 330 insertions(+), 1 deletion(-) create mode 100644 plugins/arSolrPlugin/lib/query/arSolrTermsQuery.class.php create mode 100644 test/phpunit/arSolrPlugin/lib/query/ArSolrTermsQueryTest.php diff --git a/plugins/arSolrPlugin/lib/query/arSolrTermQuery.class.php b/plugins/arSolrPlugin/lib/query/arSolrTermQuery.class.php index b9a0928ecd..b15729d93f 100644 --- a/plugins/arSolrPlugin/lib/query/arSolrTermQuery.class.php +++ b/plugins/arSolrPlugin/lib/query/arSolrTermQuery.class.php @@ -31,7 +31,7 @@ class arSolrTermQuery extends arSolrAbstractQuery * * @var string */ - protected ?string $field = null; + protected ?string $termField = null; /** * Query Term Value. diff --git a/plugins/arSolrPlugin/lib/query/arSolrTermsQuery.class.php b/plugins/arSolrPlugin/lib/query/arSolrTermsQuery.class.php new file mode 100644 index 0000000000..b3faf789c9 --- /dev/null +++ b/plugins/arSolrPlugin/lib/query/arSolrTermsQuery.class.php @@ -0,0 +1,130 @@ +. + */ + +class arSolrTermsQuery extends arSolrAbstractQuery +{ + /** + * Query Params. + * + * @var mixed + */ + protected array $query = []; + + /** + * Query Term Field. + * + * @var string + */ + protected ?string $termField = null; + + /** + * Query Term Value. + * + * @var array + */ + protected ?array $termValues = null; + + /** + * Field type. + * + * @var string + */ + protected ?string $type = null; + + /** + * Constructor. + * + * @param mixed $searchQuery + * @param null|mixed $term + */ + public function __construct($term = null) + { + if ($term) { + foreach ($term as $field => $values) { + $this->setTerms($field, $values); + } + } + } + + public function setTerms($field, $values) + { + $this->termField = $field; + $this->termValues = $values; + } + + public function getTermValues() + { + return $this->termValues; + } + + public function getTermField() + { + return $this->termField; + } + + public function getQueryParams() + { + $this->generateQueryParams(); + + return $this->query; + } + + public function setType($type) + { + if (empty($type)) { + return; + } + + $this->type = $type; + } + + public function getType() + { + return $this->type; + } + + protected function generateQueryParams() + { + $termField = $this->getTermField(); + if (!isset($termField)) { + throw new Exception('Term field is not set.'); + } + + $termValues = $this->getTermValues(); + if (!isset($termValues)) { + throw new Exception('Term values are not set.'); + } + + $type = $this->getType(); + if (!isset($type)) { + throw new Exception("Field 'type' is not set."); + } + + $queryString = implode(" OR ", $termValues); + $this->query = [ + 'query' => [ + 'edismax' => [ + 'query' => "{$type}.{$termField}:({$queryString})", + ], + ], + 'offset' => $this->offset, + 'limit' => $this->size, + ]; + } +} diff --git a/test/phpunit/arSolrPlugin/lib/query/ArSolrTermsQueryTest.php b/test/phpunit/arSolrPlugin/lib/query/ArSolrTermsQueryTest.php new file mode 100644 index 0000000000..a0b616a7a1 --- /dev/null +++ b/test/phpunit/arSolrPlugin/lib/query/ArSolrTermsQueryTest.php @@ -0,0 +1,199 @@ + [ + 'term' => null, + 'expectedField' => null, + 'expectedValue' => null, + ], + 'New arSolrTermsQuery with empty term' => [ + 'term' => ['' => []], + 'expectedField' => '', + 'expectedValue' => [], + ], + 'New arSolrTermsQuery with one string term' => [ + 'term' => ['tField' => ['tValue']], + 'expectedField' => 'tField', + 'expectedValue' => ['tValue'], + ], + 'New arSolrTermsQuery with multiple string terms' => [ + 'term' => ['tField' => ['tValue', 'tValue2']], + 'expectedField' => 'tField', + 'expectedValue' => ['tValue', 'tValue2'], + ], + ]; + } + + public function testCreateEmptySolrTermsQuery() + { + $this->termsQuery = new arSolrTermsQuery(); + $this->assertTrue($this->termsQuery instanceof arSolrTermsQuery, 'Assert plugin object is arSolrTermsQuery.'); + } + + /** + * @dataProvider createSolrTermsQueryProvider + * + * @param mixed $term + * @param mixed $expectedField + * @param mixed $expectedValue + */ + public function testCreateSolrTermsQuery($term, $expectedField, $expectedValue) + { + $this->termsQuery = new arSolrTermsQuery($term); + $actualField = $this->termsQuery->getTermField(); + $actualValues = $this->termsQuery->getTermValues(); + + $this->assertTrue($this->termsQuery instanceof arSolrTermsQuery, 'Assert plugin object is arSolrTermsQuery.'); + $this->assertSame($expectedField, $actualField, 'Passed field does not match expected field.'); + $this->assertSame($expectedValue, $actualValues, 'Passed value does not match expected value.'); + } + + public function getQueryParamsProvider(): array + { + return [ + 'Generate terms query with specified type' => [ + 'term' => ['test_field' => ['testVal']], + 'type' => 'test_type', + 'expected' => [ + 'query' => [ + 'edismax' => [ + 'query' => 'test_type.test_field:(testVal)', + ], + ], + 'offset' => 0, + 'limit' => 10, + ], + ], + 'Generate terms query with multiple values' => [ + 'term' => ['test_field' => ['testVal', 'testVal2']], + 'type' => 'test_type', + 'expected' => [ + 'query' => [ + 'edismax' => [ + 'query' => 'test_type.test_field:(testVal OR testVal2)', + ], + ], + 'offset' => 0, + 'limit' => 10, + ], + ], + ]; + } + + /** + * @dataProvider getQueryParamsProvider + * + * @param mixed $term + * @param mixed $type + * @param mixed $expected + */ + public function testGetQueryParams($term, $type, $expected) + { + $this->termsQuery = new arSolrTermsQuery($term); + $this->termsQuery->setType($type); + + $actual = $this->termsQuery->getQueryParams(); + + $this->assertSame($expected, $actual, 'Params passed do not match expected.'); + } + + public function getQueryParamsExceptionProvider(): array + { + return [ + 'Generate terms query with missing type' => [ + 'term' => ['test_field' => ['testVal']], + 'type' => '', + 'expectedException' => '\Exception', + 'expectedExceptionMessage' => 'Field \'type\' is not set.', + ], + 'Generate terms query with missing term' => [ + 'term' => [], + 'type' => 'test_type', + 'expectedException' => '\Exception', + 'expectedExceptionMessage' => 'Term field is not set.', + ], + ]; + } + + /** + * @dataProvider getQueryParamsExceptionProvider + * + * @param mixed $term + * @param mixed $type + * @param mixed $expectedException + * @param mixed $expectedExceptionMessage + */ + public function testGetQueryParamsException($term, $type, $expectedException, $expectedExceptionMessage) + { + $this->termsQuery = new arSolrTermsQuery($term); + $this->termsQuery->setType($type); + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + + $this->termsQuery->getQueryParams(); + } + + public function getQueryParamsUsingSetExceptionProvider(): array + { + return [ + 'Generate term query with missing term field' => [ + 'termField' => null, + 'termValue' => null, + 'type' => '', + 'expectedException' => '\Exception', + 'expectedExceptionMessage' => 'Term field is not set.', + ], + 'Generate term query with missing term value' => [ + 'termField' => 'tField', + 'termValue' => null, + 'type' => '', + 'expectedException' => '\Exception', + 'expectedExceptionMessage' => 'Term values are not set.', + ], + 'Generate term query with missing missing type' => [ + 'termField' => 'tField', + 'termValue' => ['tValue'], + 'type' => '', + 'expectedException' => '\Exception', + 'expectedExceptionMessage' => 'Field \'type\' is not set.', + ], + ]; + } + + /** + * @dataProvider getQueryParamsUsingSetExceptionProvider + * + * @param mixed $termField + * @param mixed $termValue + * @param mixed $type + * @param mixed $expectedException + * @param mixed $expectedExceptionMessage + */ + public function testGetQueryParamsUsingSetException($termField, $termValue, $type, $expectedException, $expectedExceptionMessage) + { + $this->termsQuery = new arSolrTermsQuery(); + $this->termsQuery->setTerms($termField, $termValue); + $this->termsQuery->setType($type); + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + + $this->termsQuery->getQueryParams(); + } +}