-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Discoverer v2 support. Spelling suggestions feature
- Loading branch information
1 parent
c9b9f5c
commit 20d23c9
Showing
14 changed files
with
283 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--- | ||
Name: discoverer-bifrost-adaptors | ||
After: discoverer-adaptors | ||
Only: | ||
envvarset: 'BIFROST_QUERY_API_KEY' | ||
--- | ||
SilverStripe\Core\Injector\Injector: | ||
# Adaptors provided by this module | ||
SilverStripe\Discoverer\Service\Interfaces\QuerySuggestionAdaptor: | ||
class: SilverStripe\DiscovererBifrost\Service\Adaptors\QuerySuggestionAdaptor | ||
SilverStripe\Discoverer\Service\Interfaces\SpellingSuggestionAdaptor: | ||
class: SilverStripe\DiscovererBifrost\Service\Adaptors\SpellingSuggestionAdaptor | ||
# Adaptors provided by the ElasticEnterprise dependency | ||
SilverStripe\Discoverer\Query\Facet\FacetAdaptor: | ||
class: SilverStripe\DiscovererElasticEnterprise\Query\Facet\FacetAdaptor | ||
SilverStripe\Discoverer\Query\Filter\CriteriaAdaptor: | ||
class: SilverStripe\DiscovererElasticEnterprise\Query\Filter\CriteriaAdaptor | ||
SilverStripe\Discoverer\Query\Filter\CriterionAdaptor: | ||
class: SilverStripe\DiscovererElasticEnterprise\Query\Filter\CriterionAdaptor | ||
SilverStripe\Discoverer\Service\Interfaces\ProcessAnalyticsAdaptor: | ||
class: SilverStripe\DiscovererElasticEnterprise\Service\Adaptors\ProcessAnalyticsAdaptor | ||
SilverStripe\Discoverer\Service\Interfaces\SearchAdaptor: | ||
class: SilverStripe\DiscovererElasticEnterprise\Service\Adaptors\SearchAdaptor | ||
|
||
SilverStripe\DiscovererElasticEnterprise\Service\Adaptors\BaseAdaptor: | ||
prefix_env_var: 'BIFROST_ENGINE_PREFIX' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
Name: discoverer-bifrost-factory | ||
Only: | ||
envvarset: 'BIFROST_QUERY_API_KEY' | ||
--- | ||
SilverStripe\Core\Injector\Injector: | ||
Elastic\EnterpriseSearch\Client.searchClient: | ||
factory: SilverStripe\DiscovererBifrost\Service\ClientFactory | ||
constructor: | ||
host: '`BIFROST_ENDPOINT`' | ||
token: '`BIFROST_QUERY_API_KEY`' | ||
http_client: '%$GuzzleHttp\Client' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
Name: discoverer-bifrost-requests | ||
Only: | ||
envvarset: 'BIFROST_QUERY_API_KEY' | ||
--- | ||
SilverStripe\Core\Injector\Injector: | ||
Elastic\EnterpriseSearch\AppSearch\Request\Search: | ||
class: SilverStripe\DiscovererBifrost\Service\Requests\Search | ||
Elastic\EnterpriseSearch\AppSearch\Request\LogClickthrough: | ||
class: SilverStripe\DiscovererBifrost\Service\Requests\ClickPost |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Processors; | ||
|
||
use SilverStripe\Core\Injector\Injectable; | ||
use SilverStripe\Discoverer\Query\Suggestion; | ||
use SilverStripe\DiscovererBifrost\Service\Requests\Params\SuggestionParams; | ||
|
||
class SuggestionParamsProcessor | ||
{ | ||
|
||
use Injectable; | ||
|
||
public function getQueryParams(Suggestion $suggestion): SuggestionParams | ||
{ | ||
$suggestionParams = SuggestionParams::create(); | ||
$suggestionParams->query = $suggestion->getQueryString(); | ||
|
||
$limit = $suggestion->getLimit(); | ||
$fields = $suggestion->getFields(); | ||
|
||
if ($limit) { | ||
$suggestionParams->size = $limit; | ||
} | ||
|
||
if ($fields) { | ||
$suggestionParams->fields = $fields; | ||
} | ||
|
||
return $suggestionParams; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Processors; | ||
|
||
use Exception; | ||
use SilverStripe\Core\Injector\Injectable; | ||
use SilverStripe\Discoverer\Service\Results\Suggestions; | ||
|
||
class SuggestionsProcessor | ||
{ | ||
|
||
use Injectable; | ||
|
||
/** | ||
* @throws Exception | ||
*/ | ||
public function getProcessedSuggestions(Suggestions $suggestions, array $response): void | ||
{ | ||
// Check that we have all critical fields in our Elastic response | ||
$this->validateResponse($response); | ||
|
||
$suggestions->setSuggestions($response['results'] ?? []); | ||
} | ||
|
||
private function validateResponse(array $response): void | ||
{ | ||
// If any errors are present, then let's throw and track what they were | ||
if (array_key_exists('errors', $response)) { | ||
throw new Exception(sprintf('Elastic response contained errors: %s', json_encode($response['errors']))); | ||
} | ||
|
||
// The top level fields that we expect to receive from Elastic for each search | ||
$results = $response['results'] ?? null; | ||
|
||
// Specifically checking is_array(), because an empty results array is a valid response | ||
if (!is_array($results)) { | ||
throw new Exception('Missing required top level fields for query suggestions: results'); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Service\Adaptors; | ||
|
||
use Elastic\EnterpriseSearch\Exception\ClientErrorResponseException; | ||
use Elastic\EnterpriseSearch\Response\Response; | ||
use SilverStripe\Core\Injector\Injector; | ||
use SilverStripe\Discoverer\Query\Suggestion; | ||
use SilverStripe\Discoverer\Service\Interfaces\QuerySuggestionAdaptor as QuerySuggestionAdaptorInterface; | ||
use SilverStripe\Discoverer\Service\Results\Suggestions; | ||
use SilverStripe\DiscovererBifrost\Processors\SuggestionParamsProcessor; | ||
use SilverStripe\DiscovererBifrost\Processors\SuggestionsProcessor; | ||
use SilverStripe\DiscovererBifrost\Service\Requests\QuerySuggestion; | ||
use SilverStripe\DiscovererElasticEnterprise\Service\Adaptors\BaseAdaptor; | ||
use Throwable; | ||
|
||
class QuerySuggestionAdaptor extends BaseAdaptor implements QuerySuggestionAdaptorInterface | ||
{ | ||
|
||
public function process(Suggestion $suggestion, string $indexName): Suggestions | ||
{ | ||
// Instantiate our Suggestions class with empty data. This will still be returned if there is an Exception | ||
// during communication with Elastic (so that the page doesn't seriously break) | ||
$suggestions = Suggestions::create(); | ||
|
||
try { | ||
$engine = $this->environmentizeIndex($indexName); | ||
$params = SuggestionParamsProcessor::singleton()->getQueryParams($suggestion); | ||
$request = QuerySuggestion::create($engine, $params); | ||
|
||
$transportResponse = $this->getClient()->appSearch()->getTransport()->sendRequest($request->getRequest()); | ||
$response = Injector::inst()->create(Response::class, $transportResponse); | ||
|
||
SuggestionsProcessor::singleton()->getProcessedSuggestions($suggestions, $response->asArray()); | ||
// If we got this far, then the request was a success | ||
$suggestions->setSuccess(true); | ||
} catch (ClientErrorResponseException $e) { | ||
$errors = (string)$e->getResponse()->getBody(); | ||
// Log the error without breaking the page | ||
$this->getLogger()->error(sprintf('Bifrost error: %s', $errors), ['bifrost' => $e]); | ||
// Our request was not a success | ||
$suggestions->setSuccess(false); | ||
} catch (Throwable $e) { | ||
// Log the error without breaking the page | ||
$this->getLogger()->error(sprintf('Bifrost error: %s', $e->getMessage()), ['bifrost' => $e]); | ||
// Our request was not a success | ||
$suggestions->setSuccess(false); | ||
} finally { | ||
return $suggestions; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Service\Adaptors; | ||
|
||
use Elastic\EnterpriseSearch\Exception\ClientErrorResponseException; | ||
use SilverStripe\Core\Injector\Injector; | ||
use SilverStripe\Discoverer\Query\Suggestion; | ||
use SilverStripe\Discoverer\Service\Interfaces\SpellingSuggestionAdaptor as SpellingSuggestionAdaptorInterface; | ||
use SilverStripe\Discoverer\Service\Results\Suggestions; | ||
use SilverStripe\DiscovererBifrost\Processors\SuggestionParamsProcessor; | ||
use SilverStripe\DiscovererBifrost\Processors\SuggestionsProcessor; | ||
use SilverStripe\DiscovererBifrost\Service\Requests\SpellingSuggestion; | ||
use SilverStripe\DiscovererElasticEnterprise\Service\Adaptors\BaseAdaptor; | ||
use Throwable; | ||
use Elastic\EnterpriseSearch\Response\Response; | ||
|
||
class SpellingSuggestionAdaptor extends BaseAdaptor implements SpellingSuggestionAdaptorInterface | ||
{ | ||
|
||
public function process(Suggestion $suggestion, string $indexName): Suggestions | ||
{ | ||
// Instantiate our Suggestions class with empty data. This will still be returned if there is an Exception | ||
// during communication with Elastic (so that the page doesn't seriously break) | ||
$suggestions = Suggestions::create(); | ||
|
||
try { | ||
$engine = $this->environmentizeIndex($indexName); | ||
$params = SuggestionParamsProcessor::singleton()->getQueryParams($suggestion); | ||
$request = SpellingSuggestion::create($engine, $params); | ||
|
||
$transportResponse = $this->getClient()->appSearch()->getTransport()->sendRequest($request->getRequest()); | ||
$response = Injector::inst()->create(Response::class, $transportResponse); | ||
|
||
SuggestionsProcessor::singleton()->getProcessedSuggestions($suggestions, $response->asArray()); | ||
// If we got this far, then the request was a success | ||
$suggestions->setSuccess(true); | ||
} catch (ClientErrorResponseException $e) { | ||
$errors = (string)$e->getResponse()->getBody(); | ||
// Log the error without breaking the page | ||
$this->getLogger()->error(sprintf('Bifrost error: %s', $errors), ['bifrost' => $e]); | ||
// Our request was not a success | ||
$suggestions->setSuccess(false); | ||
} catch (Throwable $e) { | ||
// Log the error without breaking the page | ||
$this->getLogger()->error(sprintf('Bifrost error: %s', $e->getMessage()), ['bifrost' => $e]); | ||
// Our request was not a success | ||
$suggestions->setSuccess(false); | ||
} finally { | ||
return $suggestions; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Service\Requests\Params; | ||
|
||
use SilverStripe\Core\Injector\Injectable; | ||
|
||
class SuggestionParams | ||
{ | ||
|
||
use Injectable; | ||
|
||
public ?string $query = null; | ||
|
||
public array $fields = []; | ||
|
||
public ?int $size = null; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
namespace SilverStripe\DiscovererBifrost\Service\Requests; | ||
|
||
use Elastic\EnterpriseSearch\Request\Request; | ||
use SilverStripe\Core\Injector\Injectable; | ||
use SilverStripe\DiscovererBifrost\Service\Requests\Params\SuggestionParams; | ||
|
||
class SpellingSuggestion extends Request | ||
{ | ||
|
||
use Injectable; | ||
|
||
public function __construct(string $engineName, SuggestionParams $params) | ||
{ | ||
$this->method = 'POST'; | ||
$this->path = sprintf('/api/v1/%s/spelling_suggestion', $engineName); | ||
$this->headers['Content-Type'] = 'application/json'; | ||
$this->body = $params; | ||
} | ||
|
||
} |