From 29c06250ce922f2afb38426329a8583e90301c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Thu, 28 Sep 2023 11:51:00 +0200 Subject: [PATCH 1/5] IBX-6649: Added support for spell checking --- src/lib/Handler.php | 12 +++++--- .../QueryConverter/NativeQueryConverter.php | 7 +++++ src/lib/ResultExtractor.php | 28 +++++++++++++++++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/lib/Handler.php b/src/lib/Handler.php index b2a7f60c..e61a4746 100644 --- a/src/lib/Handler.php +++ b/src/lib/Handler.php @@ -19,7 +19,7 @@ use Ibexa\Core\Base\Exceptions\NotFoundException; /** - * The Content Search handler retrieves sets of of Content objects, based on a + * The Content Search handler retrieves sets of Content objects, based on a * set of criteria. * * The basic idea of this class is to do the following: @@ -33,7 +33,7 @@ * sensible queries from all criterion definitions. * * 3) The query might be possible to optimize (remove empty statements), - * reduce singular and and or constructs… + * reduce singular and or constructs… * * 4) Additionally we might need a post-query filtering step, which filters * content objects based on criteria, which could not be converted in to @@ -153,7 +153,8 @@ public function findContent(Query $query, array $languageFilter = []) $this->gateway->findContent($query, $languageFilter), $query->facetBuilders, $query->aggregations, - $languageFilter + $languageFilter, + $query->spellcheck ); } @@ -224,7 +225,9 @@ public function findLocations(LocationQuery $query, array $languageFilter = []) return $this->locationResultExtractor->extract( $this->gateway->findLocations($query, $languageFilter), $query->facetBuilders, - $query->aggregations + $query->aggregations, + $languageFilter, + $query->spellcheck ); } @@ -478,6 +481,7 @@ public function supports(int $capabilityFlag): bool case SearchService::CAPABILITY_SCORING: case SearchService::CAPABILITY_FACETS: case SearchService::CAPABILITY_CUSTOM_FIELDS: + case SearchService::CAPABILITY_SPELLCHECK: case SearchService::CAPABILITY_ADVANCED_FULLTEXT: case SearchService::CAPABILITY_AGGREGATIONS: return true; diff --git a/src/lib/Query/Common/QueryConverter/NativeQueryConverter.php b/src/lib/Query/Common/QueryConverter/NativeQueryConverter.php index 31e49b57..2ef6aaea 100644 --- a/src/lib/Query/Common/QueryConverter/NativeQueryConverter.php +++ b/src/lib/Query/Common/QueryConverter/NativeQueryConverter.php @@ -100,6 +100,13 @@ public function convert(Query $query, array $languageSettings = []) } } + if ($query->spellcheck !== null) { + $params['spellcheck'] = 'true'; + $params['spellcheck.q'] = $query->spellcheck->getQuery(); + $params['spellcheck.count'] = 1; + $params['spellcheck.collate'] = 'true'; + } + return $params; } diff --git a/src/lib/ResultExtractor.php b/src/lib/ResultExtractor.php index fd7492d4..cdd0db9a 100644 --- a/src/lib/ResultExtractor.php +++ b/src/lib/ResultExtractor.php @@ -6,9 +6,11 @@ */ namespace Ibexa\Solr; +use Ibexa\Contracts\Core\Repository\Values\Content\Query\Spellcheck; use Ibexa\Contracts\Core\Repository\Values\Content\Search\AggregationResultCollection; use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchHit; use Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchResult; +use Ibexa\Contracts\Core\Repository\Values\Content\Search\SpellcheckResult; use Ibexa\Contracts\Solr\ResultExtractor\AggregationResultExtractor; use Ibexa\Solr\Gateway\EndpointRegistry; use Ibexa\Solr\Query\FacetFieldVisitor; @@ -49,8 +51,13 @@ public function __construct( * * @return \Ibexa\Contracts\Core\Repository\Values\Content\Search\SearchResult */ - public function extract($data, array $facetBuilders = [], array $aggregations = [], array $languageFilter = []) - { + public function extract( + $data, + array $facetBuilders = [], + array $aggregations = [], + array $languageFilter = [], + ?Spellcheck $spellcheck = null + ) { $result = new SearchResult( [ 'time' => $data->responseHeader->QTime / 1000, @@ -61,6 +68,7 @@ public function extract($data, array $facetBuilders = [], array $aggregations = $result->facets = $this->extractFacets($data, $facetBuilders, $languageFilter); $result->aggregations = $this->extractAggregations($data, $aggregations, $languageFilter); + $result->spellcheck = $this->extractSpellcheck($data, $spellcheck); foreach ($data->response->docs as $doc) { $result->searchHits[] = $this->extractSearchHit($doc, $languageFilter); @@ -186,6 +194,22 @@ protected function extractSearchHit(stdClass $doc, array $languageFilter): Searc ] ); } + + protected function extractSpellcheck(stdClass $data, ?Spellcheck $spellcheck): ?SpellcheckResult + { + if ($spellcheck === null) { + return null; + } + + if (isset($data->spellcheck)) { + $incorrect = !empty($data->spellcheck->collations); + $query = $data->spellcheck->collations[1] ?? $spellcheck->getQuery(); + + return new SpellcheckResult($query, $incorrect); + } + + return new SpellcheckResult($spellcheck->getQuery(), false); + } } class_alias(ResultExtractor::class, 'EzSystems\EzPlatformSolrSearchEngine\ResultExtractor'); From 1f156eb1d0b24a7be5d18a329949cb943b717139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Sat, 4 Nov 2023 09:19:32 +0100 Subject: [PATCH 2/5] [TMP] Switch to ibexa/core:dev-spellcheck --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 37b1e1e5..614008d9 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php": "^7.4 || ^8.0", "ext-json": "*", "ext-xmlwriter": "*", - "ibexa/core": "~4.6.0@dev", + "ibexa/core": "dev-spellcheck as 4.6.0-dev", "netgen/query-translator": "^1.0.2", "symfony/http-kernel": "^5.0", "symfony/dependency-injection": "^5.0", From 1eff3616fc1f7b593b272aedb737573bf6a54164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Sat, 4 Nov 2023 15:51:34 +0100 Subject: [PATCH 3/5] fixup! IBX-6649: Added support for spell checking --- bin/generate-solr-config.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/generate-solr-config.sh b/bin/generate-solr-config.sh index ab986946..b3547295 100755 --- a/bin/generate-solr-config.sh +++ b/bin/generate-solr-config.sh @@ -121,6 +121,10 @@ fi # Adapt autoSoftCommit to have a recommended value, and remove add-unknown-fields-to-the-schema sed -i.bak '//d' $DESTINATION_DIR/solrconfig.xml sed -i.bak 's/${solr.autoSoftCommit.maxTime:-1}/${solr.autoSoftCommit.maxTime:20}/' $DESTINATION_DIR/solrconfig.xml +# Configure spellcheck component +sed -i.bar 's/_text_<\/str>/meta_content__text_t<\/str>/' $DESTINATION_DIR/solrconfig.xml +# Add spellcheck component to /select handler +sed -i.bak 's//\n \n spellcheck<\/str>\n <\/arr>/' $DESTINATION_DIR/solrconfig.xml rm $DESTINATION_DIR/solrconfig.xml.bak From c29f462fc0f7afcc1b83ee63c7cf8798a26b1871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Tue, 5 Dec 2023 07:55:40 +0100 Subject: [PATCH 4/5] fixup! IBX-6649: Added support for spell checking --- .github/init_solr.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/init_solr.sh b/.github/init_solr.sh index f441b693..f21b4a9e 100755 --- a/.github/init_solr.sh +++ b/.github/init_solr.sh @@ -232,7 +232,11 @@ solr_cloud_configure_collection() { # modify solrconfig.xml to remove section that doesn't agree with our schema sed -i.bak '//d' ${TEMPLATE_DIR}/solrconfig.xml # Adapt autoSoftCommit to have a recommended value - sed -i.bak2 's/${solr.autoSoftCommit.maxTime:-1}/${solr.autoSoftCommit.maxTime:20}/' "${TEMPLATE_DIR}/solrconfig.xml" || exit_on_error "Can't modify file '${TEMPLATE_DIR}/solrconfig.xml'" + sed -i.bak 's/${solr.autoSoftCommit.maxTime:-1}/${solr.autoSoftCommit.maxTime:20}/' "${TEMPLATE_DIR}/solrconfig.xml" || exit_on_error "Can't modify file '${TEMPLATE_DIR}/solrconfig.xml'" + # Configure spellcheck component + sed -i.bar 's/_text_<\/str>/meta_content__text_t<\/str>/' "${TEMPLATE_DIR}/solrconfig.xml" + # Add spellcheck component to /select handler + sed -i.bak 's//\n \n spellcheck<\/str>\n <\/arr>/' "${TEMPLATE_DIR}/solrconfig.xml" } solr_cloud_upload_collection_configuration() { From 9e9b79684965d317bfdb2f16cbd47b6ac261a3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Tue, 5 Dec 2023 13:18:56 +0100 Subject: [PATCH 5/5] Revert "[TMP] Switch to ibexa/core:dev-spellcheck" This reverts commit 1f156eb1d0b24a7be5d18a329949cb943b717139. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 614008d9..37b1e1e5 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "php": "^7.4 || ^8.0", "ext-json": "*", "ext-xmlwriter": "*", - "ibexa/core": "dev-spellcheck as 4.6.0-dev", + "ibexa/core": "~4.6.0@dev", "netgen/query-translator": "^1.0.2", "symfony/http-kernel": "^5.0", "symfony/dependency-injection": "^5.0",