Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify Solr suggestions search to handle wonky case with stemming and wildcards #3990

Merged
merged 10 commits into from
Oct 25, 2024
61 changes: 47 additions & 14 deletions module/VuFind/src/VuFind/Autocomplete/Solr.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
*/
class Solr implements AutocompleteInterface
{
/**
* Parameter for mungeQuery
*
* @var string
*/
protected const NO_WILDCARD = 'NO_WILDCARD';

/**
* Autocomplete handler
*
Expand Down Expand Up @@ -171,21 +178,51 @@ protected function initSearchObject()
/**
* Process the user query to make it suitable for a Solr query.
*
* @param string $query Incoming user query
* @param string $query Incoming user query
* @param ?array $extras Array of extra parameter
*
* @return string Processed query
* @return string Processed query
*/
protected function mungeQuery($query)
protected function mungeQuery(string $query, array $extras = null): string
rominail marked this conversation as resolved.
Show resolved Hide resolved
{
// Modify the query so it makes a nice, truncated autocomplete query:
$forbidden = [':', '(', ')', '*', '+', '"', "'"];
$query = str_replace($forbidden, ' ', $query);
if (!str_ends_with($query, ' ')) {
if (
!str_ends_with($query, ' ') && (!isset($extras[self::NO_WILDCARD]) || $extras[self::NO_WILDCARD] !== true)
rominail marked this conversation as resolved.
Show resolved Hide resolved
) {
$query .= '*';
}
return $query;
}

/**
* This method perform and returns the search for a query for the autocomplete box.
*
* @param string $query The user query
* @param bool $rerunSearch Force the search to avoid cached results
*
* @return array The suggestions for the provided query
*/
protected function getSearchResultsForSuggestions(string $query, bool $rerunSearch = false): array
{
$this->searchObject->getParams()->setBasicSearch(
$query,
$this->handler
);
$this->searchObject->getParams()->setSort($this->sortField);
foreach ($this->filters as $current) {
$this->searchObject->getParams()->addFilter($current);
}

if ($rerunSearch) {
// Perform the search (force the function, not to have cached results):
$this->searchObject->performAndProcessSearch();
}
// Perform and/or return the search:
return $this->searchObject->getResults();
}

/**
* This method returns an array of strings matching the user's query for
* display in the autocomplete box.
Expand All @@ -202,18 +239,14 @@ public function getSuggestions($query)
}

try {
$this->searchObject->getParams()->setBasicSearch(
$this->mungeQuery($query),
$this->handler
);
$this->searchObject->getParams()->setSort($this->sortField);
foreach ($this->filters as $current) {
$this->searchObject->getParams()->addFilter($current);
$mungedQuery = $this->mungeQuery($query);
$searchResults = $this->getSearchResultsForSuggestions($mungedQuery);
// Re-run without wildcard, if previously ran with wildcard
if (empty($searchResults) && str_ends_with($mungedQuery, '*')) {
$mungedQuery = $this->mungeQuery($query, [self::NO_WILDCARD => true]);
$searchResults = $this->getSearchResultsForSuggestions($mungedQuery, true);
}

// Perform the search:
$searchResults = $this->searchObject->getResults();

// Build the recommendation list -- first we'll try with exact matches;
// if we don't get anything at all, we'll try again with a less strict
// set of rules.
Expand Down
7 changes: 4 additions & 3 deletions module/VuFind/src/VuFind/Autocomplete/SolrCN.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ public function setConfig($params)
/**
* Process the user query to make it suitable for a Solr query.
*
* @param string $query Incoming user query
* @param string $query Incoming user query
* @param ?array $extras Array of extra parameter
*
* @return string Processed query
* @return string Processed query
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
*/
protected function mungeQuery($query)
protected function mungeQuery(string $query, array $extras = null): string
{
// Modify the query so it makes a nice, truncated autocomplete query:
$forbidden = [':', '(', ')', '*', '+', '"'];
Expand Down
Loading