From 1fc575d81377db121ee04a078a1a3b5bd0bd7540 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Wed, 21 Mar 2018 13:27:12 +0000 Subject: [PATCH] Bug 18316 - Add weighting/relevancy options to ES query on simple search The idea is the following: if some search field(s) are weighted in search engine config page, Koha will query ES on these fields only and with the coresponding weights. Else, search is done on the entire record. Test plan (having Koha working with Elasticsearch): - apply this patch, - try searches with and without weight defined on search fields --- Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 12 ++++ Koha/SearchFields.pm | 23 +++++++ catalogue/search.pl | 8 ++- .../prog/en/modules/catalogue/advsearch.tt | 1 + t/db_dependent/Koha/SearchField.t | 70 +++++++++++++++++++++- 5 files changed, 112 insertions(+), 2 deletions(-) diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm index 8a0ead1..7f12e77 100644 --- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm +++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm @@ -92,6 +92,8 @@ sub build_query { default_operator => 'AND', default_field => '_all', lenient => JSON::true, + fields => $options{fields}, + use_dis_max => JSON::true, } }; @@ -228,9 +230,19 @@ sub build_query_compat { join( ' ', $self->_create_query_string(@search_params) ) || (), $self->_join_queries( $self->_convert_index_strings(@$limits) ) || () ); + my @weights = $params->{weight}; + my @w_fields = $params->{w_fields}; + my @fields = '_all'; + if ( defined $weights[0] ) { + for (my $i = 0 ; $i < (scalar @weights) ; $i++ ){ + push @fields, "$w_fields[$i]^$weights[$i]"; + } + } + # If there's no query on the left, let's remove the junk left behind $query_str =~ s/^ AND //; my %options; + $options{fields} = \@fields; $options{sort} = \@sort_params; $options{expanded_facet} = $params->{expanded_facet}; my $query = $self->build_query( $query_str, %options ); diff --git a/Koha/SearchFields.pm b/Koha/SearchFields.pm index 7af3c0b..3cfcec3 100644 --- a/Koha/SearchFields.pm +++ b/Koha/SearchFields.pm @@ -35,6 +35,29 @@ Koha::SearchFields - Koha SearchField Object set class =cut +=head3 weighted_fields + +my (@w_fields, @weight) = Koha::SearchFields->weighted_fields(); + +=cut + +sub weighted_fields { + my ($self) = @_; + + my ($w_fields, $weight) = ([], []); + my $fields = $self->search( + { weight => { '>' => 0, '!=' => undef } }, + { order_by => { -desc => 'weight' } } + ); + + while ( my $field = $fields->next ) { + push @$w_fields, $field->name; + push @$weight, $field->weight; + } + + return ($w_fields, $weight); +} + =head3 type =cut diff --git a/catalogue/search.pl b/catalogue/search.pl index 79ba83f..568c8a8 100755 --- a/catalogue/search.pl +++ b/catalogue/search.pl @@ -155,6 +155,7 @@ use Koha::Patrons; use Koha::SearchEngine::Search; use Koha::SearchEngine::QueryBuilder; use Koha::Virtualshelves; +use Koha::SearchFields; use URI::Escape; @@ -455,6 +456,11 @@ my $expanded_facet = $params->{'expand'}; # Define some global variables my ( $error,$query,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$query_type); +my ($w_fields, $weight); +unless ( $cgi->param('advsearch') ) { + ($w_fields, $weight) = Koha::SearchFields->weighted_fields(); +} + my $builder = Koha::SearchEngine::QueryBuilder->new( { index => $Koha::SearchEngine::BIBLIOS_INDEX } ); my $searcher = Koha::SearchEngine::Search->new( @@ -467,7 +473,7 @@ my $searcher = Koha::SearchEngine::Search->new( $query_type ) = $builder->build_query_compat( \@operators, \@operands, \@indexes, \@limits, - \@sort_by, $scan, $lang ); + \@sort_by, $scan, $lang, { w_fields => @$w_fields, weight => @$weight } ); ## parse the query_cgi string and put it into a form suitable for s my @query_inputs; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt index 51b5e34..d5fddb3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/advsearch.tt @@ -16,6 +16,7 @@