Skip to content

Commit

Permalink
Use new spelling suggestions feature. Update controller configuration (
Browse files Browse the repository at this point in the history
  • Loading branch information
chrispenny authored Nov 6, 2024
1 parent 5439350 commit 1b0912b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 15 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,53 @@ This search UI assumes that you have the following fields available in your inde
* `content` (optional)
* `body` (optional)

## Spelling suggestions (aka "did you mean")

**Not to be confused with Query suggestions (aka autocomplete).**

Spelling suggestions for queries can be enabled with the following environment variable.

```yaml
SEARCH_SPELLING_SUGGESTIONS_ENABLED=1
```

Note: Spelling suggestions is an API query that happens **after** you have received results - so it will impact your
page load times.

The spelling suggestions feature needs to know what fields you would like it to search in. By default, it **only**
provides suggestions based on the `title` field. You can add additional fields by updating the following configuration.

```yaml
SilverStripe\DiscovererSearchUI\Controller\SearchResultsController:
spelling_suggestion_fields:
- content
- body
```
By default, these suggestions will be provided when you have zero (`0`) search results. This default can be updated
through the following configruation.

```yaml
SilverStripe\DiscovererSearchUI\Controller\SearchResultsController:
result_count_for_spelling_suggestions: 5
```

By default, you will receive (up to) 1 suggestion (there aren't always spelling suggestions for a given query). This
default can be udpated through the following configuration.

```yaml
SilverStripe\DiscovererSearchUI\Controller\SearchResultsController:
spelling_suggestions_limit: 5
```

Some services support both "raw" and "foramtted" results for spelling suggestions. Our default behaviour is to **not**
request formatted suggestions. You can enable this in your requests through the following configuration.

```yaml
SilverStripe\DiscovererSearchUI\Controller\SearchResultsController:
spelling_suggestions_formatted: true
```

## Customisations

The out of the box `SearchResultsController` comes with 3 extension points that will allow you to modify the search
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
],
"require": {
"silverstripe/framework": "^5",
"silverstripe/silverstripe-discoverer": "^1.2"
"silverstripe/silverstripe-discoverer": "^2"
},
"config": {
"allow-plugins": {
Expand Down
37 changes: 26 additions & 11 deletions src/Controller/SearchResultsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
class SearchResultsController extends PageController
{

public const ENV_SUGGESTIONS_ENABLED = 'SEARCH_SUGGESTIONS_ENABLED';
private const ENV_SPELLING_SUGGESTIONS_ENABLED = 'SEARCH_SPELLING_SUGGESTIONS_ENABLED';

private static array $allowed_actions = [
'SearchForm',
Expand All @@ -35,9 +35,15 @@ class SearchResultsController extends PageController

private static int $per_page = 10;

private static int $result_count_for_suggestions = 0;
private static int $result_count_for_spelling_suggestions = 0;

private static int $suggestions_limit = 4;
private static int $spelling_suggestions_limit = 1;

private static bool $spelling_suggestions_formatted = false;

private static array $spelling_suggestion_fields = [
'title',
];

private ?Results $results = null;

Expand Down Expand Up @@ -84,7 +90,7 @@ public function SearchForm(): Form

public function SearchResults(): ?Results
{
// Local cache to make sure we don't perform this task more than one (@see QuerySuggestions())
// Local cache to make sure we don't perform this task more than one (@see SpellingSuggestions())
if ($this->results) {
return $this->results;
}
Expand Down Expand Up @@ -123,21 +129,22 @@ public function SearchResults(): ?Results
return $this->results;
}

public function QuerySuggestions(): ?Suggestions
public function SpellingSuggestions(): ?Suggestions
{
if (!Environment::getEnv(self::ENV_SUGGESTIONS_ENABLED)) {
if (!Environment::getEnv(self::ENV_SPELLING_SUGGESTIONS_ENABLED)) {
return null;
}

// Get the search results for this request
$results = $this->SearchResults();

// No search has been performed yet
if (!$results) {
return null;
}

// Our results contain enough records that we don't want to query for suggestions
if ($results->getRecords()->count() > $this->config()->get('result_count_for_suggestions')) {
if ($results->getRecords()->count() > $this->config()->get('result_count_for_spelling_suggestions')) {
return null;
}

Expand All @@ -146,24 +153,32 @@ public function QuerySuggestions(): ?Suggestions
$fieldKeywords = $this->config()->get('field_keywords');
// The keywords that are being searched
$keywords = $request->getVar($fieldKeywords);
// The fields that we want to query on
$suggestionFields = $this->config()->get('spelling_suggestion_fields');
// Whether we want to have formatted results (if supported by our search service)
$suggestionsFormatted = $this->config()->get('spelling_suggestions_formatted');

// The index variant that we are fetching records from (as defined under `indexes` in search.yml)
$index = $this->config()->get('index_variant');

$service = SearchService::singleton();
$suggestion = Suggestion::create($keywords);
$suggestion->setLimit($this->config()->get('suggestions_limit'));
$suggestion = Suggestion::create(
$keywords,
$this->config()->get('spelling_suggestions_limit'),
$suggestionFields,
$suggestionsFormatted
);

$this->invokeWithExtensions('updateSuggestionQuery', $suggestion);

$suggestions = $service->querySuggestion($suggestion, $index);
$suggestions = $service->spellingSuggestion($suggestion, $index);

if (!$suggestions->getSuggestions()) {
return null;
}

$suggestions->setTargetQueryUrl($this->dataRecord->Link());
$suggestions->setTargetQueryStringField($this->config()->get('field_keywords'));
$suggestions->setTargetQueryStringField($fieldKeywords);

return $suggestions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<% loop $Me %>
<% if $Up.TargetQueryUrl && $Up.TargetQueryStringField %>
<li class="discoverer-suggestion">
<a href="{$Up.TargetQueryUrl}?{$Up.TargetQueryStringField}={$Me}"
<a href="{$Up.TargetQueryUrl}?{$Up.TargetQueryStringField}={$Me.Raw}"
class="discoverer-suggestion__link"
>$Me</a>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
$SearchForm
</div>

<% if $QuerySuggestions %>
<% if $SpellingSuggestions %>
<div class="discoverer-suggestions">
<h2><%t SilverStripe\DiscovererSearchUI\Page\SearchResults.SearchSuggestions 'Search suggestions' %></h2>

$QuerySuggestions
$SpellingSuggestions
</div>
<% end_if %>

Expand Down

0 comments on commit 1b0912b

Please sign in to comment.