diff --git a/README.md b/README.md index 9a0e9d1..ff1f9c0 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ - [Collection Search](#collection-search) - [Paging](#paging) - [Sorting](#sorting) + - [Search Highlighting](#search-highlighting) - [Result Summary](#result-summary) @@ -359,6 +360,27 @@ available in the pager block (*documented below*). ![image](./docs/sort_criteria.png) +### Search Highlighting + +1. Add Search Excerpt to the Advanced Search View. + - Navigate to `/admin/structure/views/view/advanced_search`. In the `Fields` section, click `Add`, then select `Search Excerpt`.' + + ![image](https://user-images.githubusercontent.com/106131209/225054405-122b2d9d-1aec-4ac9-9e72-8a99a679f8e6.png) + +2. Turn on Search API highlight processor + - Navigate to `/admin/config/search/search-api` > Edit Index > Processors > Enable Highlight processor. + + ![image](https://user-images.githubusercontent.com/106131209/225055386-8c2d279c-e4c6-4123-8e89-f139ac4862d9.png) + + - At the bottom of the form, under Processor Settings > Highlight > Select `Create excerpt`. + + ![image](https://user-images.githubusercontent.com/106131209/225055763-33e9c122-e2aa-452e-9158-ebf24076f0f8.png) + +3. Configure Solr Server. + - Navigate to `/admin/config/search/search-api` > Edit Server > Configure Solr backend > Advanced > Select `Retrieve highlighted snippets`. + + ![image](https://user-images.githubusercontent.com/106131209/225057771-c42c5751-c63f-4170-9b48-d443f02b7d8f.png) + ### Result Summary In your view, in the `Header` section, clikc `Add`, then search and select for "Result summary". diff --git a/src/AdvancedSearchQuery.php b/src/AdvancedSearchQuery.php index 694d003..90acfe5 100644 --- a/src/AdvancedSearchQuery.php +++ b/src/AdvancedSearchQuery.php @@ -12,6 +12,7 @@ use Drupal\search_api\Query\QueryInterface as DrupalQueryInterface; use Drupal\views\ViewExecutable; use Solarium\Core\Query\QueryInterface as SolariumQueryInterface; use Symfony\Component\HttpFoundation\Request; +use Drupal\search_api_solr\Utility\Utility as SearchAPISolrUtility; /** * Alter current search query / view from using URL parameters. @@ -252,6 +253,27 @@ class AdvancedSearchQuery { $dismax->setQueryFields($query_fields); } } + + if ($backend->getConfiguration()['highlight_data']) { + // Just highlight string and text fields to avoid Solr exceptions. + $highlighted_fields = array_filter(array_unique($fields_list), function ($v) { + return preg_match('/^t.*?[sm]_/', $v) || preg_match('/^s[sm]_/', $v); + }); + + if (empty($highlighted_fields)) { + $highlighted_fields = ['*']; + } + + $this->setHighlighting($solarium_query, $search_api_query, $highlighted_fields); + + // The Search API Highlight processor checks if the 'keys' field of + // the Search API Query is non-empty before creating an excerpt. + // Since we are getting the highlighting result from Solr instead + // of using the Search API processor to create one, we just need + // make this field non-empty. + $search_api_query->keys("advanced search"); + } + $solarium_query->setQuery($q); } } @@ -344,4 +366,60 @@ class AdvancedSearchQuery { return $url; } + /** + * Sets the highlighting parameters. + * + * @param \Solarium\QueryType\Select\Query\Query $solarium_query + * The Solarium select query object. + * @param \Drupal\search_api\Query\QueryInterface $query + * The query object. + * @param array $highlighted_fields + * (optional) The solr fields to be highlighted. + */ + protected function setHighlighting(SolariumQueryInterface $solarium_query, DrupalQueryInterface $search_api_query, array $highlighted_fields = []) { + $index = $search_api_query->getIndex(); + $settings = SearchAPISolrUtility::getIndexSolrSettings($index); + $highlighter = $settings['highlighter']; + + $hl = $solarium_query->getHighlighting(); + $hl->setSimplePrefix('[HIGHLIGHT]'); + $hl->setSimplePostfix('[/HIGHLIGHT]'); + $hl->setSnippets($highlighter['highlight']['snippets']); + $hl->setFragSize($highlighter['highlight']['fragsize']); + $hl->setMergeContiguous($highlighter['highlight']['mergeContiguous']); + $hl->setRequireFieldMatch($highlighter['highlight']['requireFieldMatch']); + + // Overwrite Solr default values only if required to have shorter request + // strings. + if (51200 != $highlighter['maxAnalyzedChars']) { + $hl->setMaxAnalyzedChars($highlighter['maxAnalyzedChars']); + } + if ('gap' !== $highlighter['fragmenter']) { + $hl->setFragmenter($highlighter['fragmenter']); + if ('regex' !== $highlighter['fragmenter']) { + $hl->setRegexPattern($highlighter['regex']['pattern']); + if (0.5 != $highlighter['regex']['slop']) { + $hl->setRegexSlop($highlighter['regex']['slop']); + } + if (10000 != $highlighter['regex']['maxAnalyzedChars']) { + $hl->setRegexMaxAnalyzedChars($highlighter['regex']['maxAnalyzedChars']); + } + } + } + if (!$highlighter['usePhraseHighlighter']) { + $hl->setUsePhraseHighlighter(FALSE); + } + if (!$highlighter['highlightMultiTerm']) { + $hl->setHighlightMultiTerm(FALSE); + } + if ($highlighter['preserveMulti']) { + $hl->setPreserveMulti(TRUE); + } + + foreach ($highlighted_fields as $highlighted_field) { + // We must not set the fields at once using setFields() to not break + // the altered queries. + $hl->addField($highlighted_field); + } + } }