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

Search Result Explanation Feature #3069

Merged
merged 33 commits into from Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f448d03
implemented explain feature
ThoWagen Sep 5, 2023
55910ce
Merge branch 'dev' into pull-request/explain
ThoWagen Sep 5, 2023
c37a9eb
ran php-cs-fixer
ThoWagen Sep 5, 2023
e032793
Merge branch 'dev' into pull-request/explain
demiankatz Nov 6, 2023
6e9bb9c
removed spaces
ThoWagen Nov 7, 2023
ce9934b
fixed translations
ThoWagen Nov 7, 2023
7a64626
Merge branch 'dev' into pull-request/explain
ThoWagen Nov 13, 2023
56abe80
explain element view helper and fixes
ThoWagen Nov 13, 2023
a7ccbb7
bold field name
ThoWagen Nov 13, 2023
a1e758c
Merge branch 'dev' into pull-request/explain
ThoWagen Nov 16, 2023
e9ad21d
changed explain link and added translations
ThoWagen Nov 16, 2023
a908e72
explain for search2 and small fixes
ThoWagen Nov 16, 2023
5e6590e
Merge branch 'dev' into pull-request/explain
ThoWagen Nov 16, 2023
3e0ea68
support synonyms
ThoWagen Nov 17, 2023
7416282
Merge branch 'dev' into pull-request/explain
ThoWagen Nov 30, 2023
3183bc4
small fixes
ThoWagen Nov 30, 2023
2017bf8
refactored
ThoWagen Nov 30, 2023
26e2173
fixed resultlist if no explain information is provided
ThoWagen Nov 30, 2023
741641e
small fixes
ThoWagen Dec 1, 2023
5579744
always using arrays for fieldName, fieldValue and exactMatch
ThoWagen Dec 1, 2023
e5a0dcb
using translate instead of transEsc
ThoWagen Dec 6, 2023
e92a973
Merge branch 'dev' into pull-request/explain
ThoWagen Dec 6, 2023
fcaf9b9
Fix typo.
demiankatz Dec 18, 2023
5d4fb91
removed unused translation and moved added explain_ prefixes
ThoWagen Jan 11, 2024
872b956
created search2default factory
ThoWagen Jan 11, 2024
5460f06
Merge branch 'pull-request/explain' of github.com:ThoWagen/vufind int…
ThoWagen Jan 11, 2024
4089589
Merge branch 'dev' into pull-request/explain
ThoWagen Jan 11, 2024
0ea5a24
improved search2default factory
ThoWagen Jan 12, 2024
fdc11b3
fixed typos
ThoWagen Jan 12, 2024
ff69e61
added Mink test class
ThoWagen Jan 12, 2024
ca46205
fixed typo
ThoWagen Jan 12, 2024
198c4c8
added questionmark for field description
ThoWagen Jan 15, 2024
ad7d405
Merge branch 'dev' into pull-request/explain
demiankatz Jan 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.xml
Expand Up @@ -376,6 +376,8 @@
<target name="copynodemodules">
<!-- autocomplete.js -->
<copy file="${srcdir}/node_modules/autocomplete.js/autocomplete.js" todir="${srcdir}/themes/bootstrap3/js/vendor" overwrite="true" />
<!-- chart.js -->
<copy file="${srcdir}/node_modules/chart.js/dist/chart.umd.js" tofile="${srcdir}/themes/bootstrap3/js/vendor/chart.js" overwrite="true" />
<!-- jstree -->
<copy todir="${srcdir}/themes/bootstrap3/js/vendor/jsTree" overwrite="true">
<fileset dir="${srcdir}/node_modules/jstree/dist/" >
Expand Down
6 changes: 6 additions & 0 deletions config/vufind/Search2.ini
Expand Up @@ -205,6 +205,12 @@ content[] = FacetList:Search2
;options[ttl] = 300
;options[cache_dir] = "/tmp/search-cache"

[Explain]
;enabled = true
;minPercent = 0
;maxFields = -1
;decimalPlaces = 2

; ---------- facets.ini settings ----------

[Results]
Expand Down
18 changes: 17 additions & 1 deletion config/vufind/searches.ini
Expand Up @@ -124,7 +124,8 @@ always_display_reset_filters = false
;default_filters[] = "(format:Book AND institution:MyInstitution)"

; Default record fields to fetch from Solr when searching (Solr parameter 'fl')
; Default is "*" (since VuFind 7.0). To restore previous setting, just uncomment
; Default is "*" (since VuFind 7.0). When Explain is enabled 'score' will automatically be
; added if it is not already included. To restore previous setting, just uncomment
; line below.
;default_record_fields = "*,score"

Expand Down Expand Up @@ -896,3 +897,18 @@ maxLimit = 100
; Filters are defined as in [RawHiddenFilters] in order to handle more complex
; filter combinations.
;0 = "format:Video"

; This section provides settings for the explain feature. When enabled the result
; list contains links to the explanation why a title was found and how the relevance
; is calculated.
[Explain]
; The explain feature is disabled by default. Uncomment the following line to enable it
;enabled = true
EreMaijala marked this conversation as resolved.
Show resolved Hide resolved
; The explanation is split into the main fields and a rest.
; minPercent gives a lower bound for fields to be included. All fields with
; a percentage lower than minPercent are summarized in the rest.
;minPercent = 0
; maxFields gives a upper bound for the number of main fields. Set negative for no boundary.
;maxFields = -1
; Number of decimal places to be displayed.
;decimalPlaces = 2
5 changes: 5 additions & 0 deletions languages/IndexFieldDescription/de.ini
@@ -0,0 +1,5 @@
;description of fields in explain
allfields_unstemmed = 'Kopiert aus "Alle Felder"'
fulltext_unstemmed = 'Kopiert von "Volltext"'
title_alt = "alternativer Titel"
unknown = "Feldname unbekannt"
5 changes: 5 additions & 0 deletions languages/IndexFieldDescription/en.ini
@@ -0,0 +1,5 @@
;description of fields in explain
allfields_unstemmed = "copyFielded from allfields"
fulltext_unstemmed = "copyFielded from fulltext"
title_alt = "alternate title(s)"
unknown = "field name is unknown"
19 changes: 19 additions & 0 deletions languages/de.ini
Expand Up @@ -334,6 +334,7 @@ Description = "Beschreibung"
Desired Username = "Gewünschter Benutzername"
Detailed View = "Detailansicht"
Details = "Details"
Difference to top result relevance = "Differenz zu der top Relevanz"
Displaying the top = "Angezeigt werden die ersten"
Document Inspector = "Dokumentprüfer"
Document Type = "Publikationsart"
Expand Down Expand Up @@ -409,6 +410,21 @@ Exception = "Exception"
Excerpt = "Ausschnitt"
exclude_facet = "[ausschließen]"
exclude_newspapers = "Ohne Zeitungsartikel"
explain_boost = " * %%boost%% (Boost)"
explain_boost_description = "(Boost) = %%boost_description%%"
explain_compared = "Relevanz im Vergleich zu der Trefferrelevanz des Top Treffers"
explain_coord = " * %%coord%% (Ausgleich von Anzahl der Treffer im Vergleich zur Suche)"
explain_difference_score = "Differenz zum Topscore"
explain_disabled = "Explain ist für %%searchClassId%% deaktiviert"
explain_modified_value = "Produkt von %%relevanceValue%% (Relevanzwert)"
explain_modifier = "mit dem Modifier: %%modifier%%"
explain_record_score = "Titlescore"
explain_relevance = "Record Id: %%recordId%% gefunden mit einem Relevanzwert von %%relevanceValue%%"
explain_relevance_score = "Relevanzscore"
explain_result_list_chart_title = "Score: %%score%%"
explain_result_list_hint = "Relevanzscore. Klicke für eine detailliertere Erklärung."
explain_sum = "Summe"
Explanation for search = "Explain für Suche"
Export = "Export"
Export Favorites = "Favoriten exportieren"
Export Items = "Exportieren"
Expand Down Expand Up @@ -1130,6 +1146,7 @@ relais_success_message = "Bestellnummer %%id%% wurde angelegt. Sie erhalten eine
Related Author = "Ähnliche Verfasser"
Related Items = "Ähnliche Datensätze"
Related Subjects = "Ähnliche Schlagworte"
Relevance = "Relevanz"
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
Remove filter = "Suchfilter entfernen"
Remove Filters = "Suchfilter entfernen"
Remove from Book Bag = "Aus der Zwischenablage entfernen"
Expand Down Expand Up @@ -1334,6 +1351,7 @@ switchquery_truncatechar = "Verkürzen Sie Ihren Suchbegriff um mehr Treffer zu
switchquery_unwantedbools = "Die Wörter AND, OR und NOT beeinflussen die Suchergebnisse; versuchen Sie es mit Anführungszeichen"
switchquery_unwantedquotes = "Eine Suche ohne Anführungszeichen kann mehr Ergebnisse liefern"
switchquery_wildcard = "Verwenden Sie das Zeichen für die Wildcard um Wortvarianten zu berücksichtigen"
Synonym = "Synonym"
System Unavailable = "System nicht verfügbar"
Table of Contents = "Inhaltsangabe"
Table of Contents unavailable = "Keine Inhaltsangabe verfügbar"
Expand Down Expand Up @@ -1372,6 +1390,7 @@ Too Many Email Recipients = "Zu viele E-Mail-Adressen"
too_many_favorites = "Diese Liste ist zu gross um auf einmal angezeigt zu werden. Versuchen Sie Ihre Favoriten in weitere Listen zu unterteilen oder mittels Tags einzuschränken."
too_many_new_items = "Es gibt zu viele Einträge um in einer einzigen Liste angezeigt zu werden. Versuchen Sie Ihre Suche weiter einzuschränken."
too_many_reserves = "Es gibt zu viele Vormerkungen um in einer einzigen Liste angezeigt zu werden. Versuchen Sie Ihre Suche weiter einzuschränken."
Top Result Relevance = "Top Treffer Relevanz"
top_facet_label = "%%label%% innerhalb Ihrer Suche."
Topic = "Thema"
Topics = "Themen"
Expand Down
19 changes: 19 additions & 0 deletions languages/en.ini
Expand Up @@ -339,6 +339,7 @@ Description = "Description"
Desired Username = "Desired Username"
Detailed View = "Detailed View"
Details = "Staff View"
Difference to top result relevance = "Difference to top result relevance"
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
Displaying the top = "Displaying the top"
Document Inspector = "Document Inspector"
Document Type = "Document Type"
Expand Down Expand Up @@ -414,6 +415,21 @@ Exception = "Exception"
Excerpt = "Excerpt"
exclude_facet = "Exclude matching results"
exclude_newspapers = "Exclude newspaper articles"
explain_boost = " * %%boost%% (boost)"
explain_boost_description = "(boost) = %%boost_description%%"
explain_compared = "Relevance in comparison to the relevance of the top result"
explain_coord = " * %%coord%% (adjust for number of matches compared to search)"
explain_difference_score = "difference to top score"
explain_disabled = "Explain is deactivated for %%searchClassId%%"
explain_modified_value = "Product of %%relevanceValue%% (relevance value)"
explain_modifier = "with a modifier of %%modifier%%"
explain_record_score = "record score"
explain_relevance = "Record Id: %%recordId%% found with a relevance value of %%relevanceValue%%"
explain_relevance_score = "Relevance Score"
explain_result_list_chart_title = "Score: %%score%%"
explain_result_list_hint = "Relevance score. Click to see detailed explanation."
explain_sum = "sum"
Explanation for search = "Explanation for search"
Export = "Export"
Export Favorites = "Export Items"
Export Items = "Export Items"
Expand Down Expand Up @@ -1135,6 +1151,7 @@ relais_success_message = "Request id #%%id%% was created. You will receive a con
Related Author = "Related Author"
Related Items = "Related Items"
Related Subjects = "Related Subjects"
Relevance = "Relevance"
Remove filter = "Remove Filter"
Remove Filters = "Remove Filters"
Remove from Book Bag = "Remove from Book Bag"
Expand Down Expand Up @@ -1339,6 +1356,7 @@ switchquery_truncatechar = "Shorten your search query to broaden your results"
switchquery_unwantedbools = "The words AND, OR and NOT may confuse the search; try adding quotes"
switchquery_unwantedquotes = "Removing quotes may allow a broader search"
switchquery_wildcard = "Adding a wildcard symbol may retrieve word variants"
Synonym = "Synonym"
System Unavailable = "System Unavailable"
Table of Contents = "Table of Contents"
Table of Contents unavailable = "Table of Contents unavailable"
Expand Down Expand Up @@ -1377,6 +1395,7 @@ Too Many Email Recipients = "Too Many Email Recipients"
too_many_favorites = "This list is too large to display all at once. Try rearranging your saved items into more lists or limiting using tags."
too_many_new_items = "There are too many new items to display in a single list. Try limiting your search."
too_many_reserves = "There are too many course reserves to display in a single list. Try limiting your search."
Top Result Relevance = "Top Result Relevance"
top_facet_label = "%%label%% within your search."
Topic = "Topic"
Topics = "Topics"
Expand Down
4 changes: 3 additions & 1 deletion module/VuFind/config/module.config.php
Expand Up @@ -466,6 +466,7 @@
'VuFind\Role\PermissionManager' => 'VuFind\Role\PermissionManagerFactory',
'VuFind\Role\PermissionDeniedManager' => 'VuFind\Role\PermissionDeniedManagerFactory',
'VuFind\Search\BackendManager' => 'VuFind\Search\BackendManagerFactory',
'VuFind\Search\Explanation\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
'VuFind\Search\FacetCache\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
'VuFind\Search\Factory\UrlQueryHelperFactory' => 'Laminas\ServiceManager\Factory\InvokableFactory',
'VuFind\Search\History' => 'VuFind\Search\HistoryFactory',
Expand Down Expand Up @@ -656,6 +657,7 @@
'related' => [ /* See VuFind\Related\PluginManager for defaults */ ],
'resolver_driver' => [ /* See VuFind\Resolver\Driver\PluginManager for defaults */ ],
'search_backend' => [ /* See VuFind\Search\BackendRegistry for defaults */ ],
'search_explanation' => [ /* See VuFind\Search\Explanation\PluginManager for defaults */ ],
'search_facetcache' => [ /* See VuFind\Search\FacetCache\PluginManager for defaults */ ],
'search_options' => [ /* See VuFind\Search\Options\PluginManager for defaults */ ],
'search_params' => [ /* See VuFind\Search\Params\PluginManager for defaults */ ],
Expand Down Expand Up @@ -711,7 +713,7 @@
// Define non tab record actions
$nonTabRecordActions = [
'AddComment', 'DeleteComment', 'AddTag', 'DeleteTag', 'Save', 'Email', 'SMS',
'Cite', 'Export', 'RDF', 'Hold', 'Home', 'StorageRetrievalRequest',
'Cite', 'Explain', 'Export', 'RDF', 'Hold', 'Home', 'StorageRetrievalRequest',
'AjaxTab', 'ILLRequest', 'PDF', 'Epub', 'LinkedText', 'Permalink', 'Rating',
];

Expand Down
28 changes: 28 additions & 0 deletions module/VuFind/src/VuFind/Controller/AbstractRecord.php
Expand Up @@ -742,6 +742,34 @@ public function rdfAction()
return $this->exportAction();
}

/**
* Show explanation for why a record was found and how its relevancy is computed
*
* @return mixed
*/
public function explainAction()
{
$record = $this->loadRecord();

$view = $this->createViewModel();
$view->setTemplate('record/explain');
if (!$record->tryMethod('explainEnabled')) {
$view->disabled = true;
return $view;
}

$explanation = $this->serviceLocator
->get(\VuFind\Search\Explanation\PluginManager::class)
->get($record->getSourceIdentifier());

$params = $explanation->getParams();
$params->initFromRequest($this->getRequest()->getQuery());
$explanation->performRequest($record->getUniqueID());

$view->explanation = $explanation;
return $view;
}

/**
* Load the record requested by the user; note that this is not done in the
* init() method since we don't want to perform an expensive search twice
Expand Down
1 change: 1 addition & 0 deletions module/VuFind/src/VuFind/Controller/AbstractSearch.php
Expand Up @@ -364,6 +364,7 @@ protected function getSearchResultsView($setupCallback = null)
// Send both GET and POST variables to search class:
$request = $this->getRequest()->getQuery()->toArray()
+ $this->getRequest()->getPost()->toArray();
$view->request = $request;

$lastView = $this->getSearchMemory()
->retrieveLastSetting($this->searchClassId, 'view');
Expand Down
19 changes: 19 additions & 0 deletions module/VuFind/src/VuFind/RecordDriver/SolrDefault.php
Expand Up @@ -122,6 +122,13 @@ class SolrDefault extends DefaultRecord implements
*/
protected $searchService = null;

/**
* If the explain features is enabled
*
* @var bool
*/
protected $explainEnabled = false;

/**
* Constructor
*
Expand Down Expand Up @@ -154,6 +161,8 @@ public function __construct(
= !isset($mainConfig->Hierarchy->simpleContainerLinks)
? false : $mainConfig->Hierarchy->simpleContainerLinks;

$this->explainEnabled = $searchSettings->Explain->enabled ?? false;

parent::__construct($mainConfig, $recordConfig, $searchSettings);
}

Expand Down Expand Up @@ -329,4 +338,14 @@ public function getWorkKeys()
{
return $this->fields['work_keys_str_mv'] ?? [];
}

/**
* Get if the explain features is enabled.
*
* @return bool
*/
public function explainEnabled()
{
return $this->explainEnabled;
}
}
Expand Up @@ -67,8 +67,15 @@ public function __invoke(
if (!empty($options)) {
throw new \Exception('Unexpected options sent to factory.');
}
$config = $container->get(\VuFind\Config\PluginManager::class)
->get('searches');

if (str_contains($requestedName, 'Search2')) {
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
$config = $container->get(\VuFind\Config\PluginManager::class)
->get('Search2');
} else {
$config = $container->get(\VuFind\Config\PluginManager::class)
->get('searches');
}

$finalOptions = [null, $config];
return parent::__invoke($container, $requestedName, $finalOptions);
}
Expand Down