From 2d8fb7f82c550166f69c92afb9eb1118f3381973 Mon Sep 17 00:00:00 2001 From: Simon Erkelens Date: Tue, 31 Mar 2020 19:15:50 +1300 Subject: [PATCH] Fix issue #209 and #210 (#211) * Fix issue #209 and #210 Extract some logic * Add more thorough test --- docs/03-Usage.md | 7 +++++-- src/Factories/QueryComponentFactory.php | 21 ++++++++++++++++++--- src/Indexes/BaseIndex.php | 20 +++++++++++++++++--- src/Traits/QueryTraits/BaseQueryTrait.php | 19 +++++++++++++++++++ tests/unit/BaseIndexTest.php | 16 ++++++++++++++++ 5 files changed, 75 insertions(+), 8 deletions(-) diff --git a/docs/03-Usage.md b/docs/03-Usage.md index c4cd02b3..17c86447 100644 --- a/docs/03-Usage.md +++ b/docs/03-Usage.md @@ -307,8 +307,11 @@ class SearchController extends PageController $sort = isset($data['Order']) ? strtolower($data['Order']) : 'asc'; // Set the sorting. This can be an array of multiple sorts - $params['sort'] = MySortableClass::class . '_Created ' . $sort; - $query->setSort($params); + $params['sort'] = [MySortableClass::class . '_Created ' => $sort]; + $query->setSort($params['sort']); + // Alternative: + $query->addSort(MySortableClass::class . '_Created', $sort); + // Execute the search $result = $index->doSearch($query); diff --git a/src/Factories/QueryComponentFactory.php b/src/Factories/QueryComponentFactory.php index c6e72997..0dc23e7b 100644 --- a/src/Factories/QueryComponentFactory.php +++ b/src/Factories/QueryComponentFactory.php @@ -226,12 +226,10 @@ public function setIndex(BaseIndex $index): self protected function buildTerms(): void { $terms = $this->query->getTerms(); - $boostTerms = $this->getBoostTerms(); foreach ($terms as $search) { - $term = $search['text']; - $term = $this->escapeSearch($term); + $term = $this->getBuildTerm($search); $postfix = $this->isFuzzy($search); // We can add the same term multiple times with different boosts // Not ideal, but it might happen, so let's add the term itself only once @@ -308,4 +306,21 @@ protected function buildSpellcheck(): void $spellcheck->setExtendedResults(true); $spellcheck->setCollateExtendedResults(true); } + + /** + * Get the escaped search string, or, if empty, a global search + * + * @param array $search + * @return string + */ + protected function getBuildTerm($search) + { + $term = $search['text']; + $term = $this->escapeSearch($term); + if ($term === '') { + $term = '*:*'; + } + + return $term; + } } diff --git a/src/Indexes/BaseIndex.php b/src/Indexes/BaseIndex.php index fbffec2b..d3f26e53 100644 --- a/src/Indexes/BaseIndex.php +++ b/src/Indexes/BaseIndex.php @@ -88,6 +88,10 @@ abstract class BaseIndex * @var array The query terms as an array */ protected $queryTerms = []; + /** + * @var Query Query that will hit the client + */ + protected $clientQuery; /** * @var bool Signify if a retry should occur if nothing was found and there are suggestions to follow */ @@ -199,12 +203,14 @@ public function doSearch(BaseQuery $query) { SiteState::alterQuery($query); // Build the actual query parameters - $clientQuery = $this->buildSolrQuery($query); + $this->clientQuery = $this->buildSolrQuery($query); + // Set the sorting + $this->clientQuery->addSorts($query->getSort()); - $this->extend('onBeforeSearch', $query, $clientQuery); + $this->extend('onBeforeSearch', $query, $this->clientQuery); try { - $result = $this->client->select($clientQuery); + $result = $this->client->select($this->clientQuery); } catch (Exception $error) { // @codeCoverageIgnoreStart $logger = new SolrLogger(); @@ -415,4 +421,12 @@ public function getQueryFactory(): QueryComponentFactory { return $this->queryFactory; } + + /** + * @return Query + */ + public function getClientQuery(): Query + { + return $this->clientQuery; + } } diff --git a/src/Traits/QueryTraits/BaseQueryTrait.php b/src/Traits/QueryTraits/BaseQueryTrait.php index 1cc0070f..b795a8d9 100644 --- a/src/Traits/QueryTraits/BaseQueryTrait.php +++ b/src/Traits/QueryTraits/BaseQueryTrait.php @@ -51,6 +51,11 @@ trait BaseQueryTrait */ protected $exclude = []; + /** + * @var array Sorting order + */ + protected $sort = []; + /** * Each boosted query needs a separate addition! * e.g. $this->addTerm('test', ['MyField', 'MyOtherField'], 3) @@ -138,4 +143,18 @@ public function addFacetFilter($field, $value): self return $this; } + + /** + * Add a field to sort on + * + * @param string $field + * @param string $direction + * @return $this + */ + public function addSort($field, $direction): self + { + $this->sort[$field] = $direction; + + return $this; + } } diff --git a/tests/unit/BaseIndexTest.php b/tests/unit/BaseIndexTest.php index a04a7d39..0b31b05b 100644 --- a/tests/unit/BaseIndexTest.php +++ b/tests/unit/BaseIndexTest.php @@ -308,6 +308,22 @@ public function testDoSearch() $this->assertInstanceOf(ArrayList::class, $result->getSpellcheck()); $this->assertGreaterThan(0, $result->getSpellcheck()->count()); $this->assertNotEmpty($result->getCollatedSpellcheck()); + + $index = new CircleCITestIndex(); + $query = new BaseQuery(); + $query->addTerm(''); + $index->doSearch($query); + + $this->assertEquals(['*:*'], $index->getQueryTerms()); + + $index = new CircleCITestIndex(); + $query = new BaseQuery(); + $query->addTerm('test'); + $query->addSort('SiteTree_Title', 'asc'); + $index->doSearch($query); + + $this->assertEquals(['test'], $index->getQueryTerms()); + $this->assertArrayHasKey('SiteTree_Title', $index->getClientQuery()->getSorts()); } public function testDoRetry()