Bugzilla – Attachment 74419 Details for
Bug 20589
Add field boosting and use elastic query fields parameter instead of deprecated _all
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 20589: Add field boosting and use query_string fields parameter
Bug-20589-Add-field-boosting-and-use-querystring-f.patch (text/plain), 31.71 KB, created by
David Gustafsson
on 2018-04-18 09:24:01 UTC
(
hide
)
Description:
Bug 20589: Add field boosting and use query_string fields parameter
Filename:
MIME Type:
Creator:
David Gustafsson
Created:
2018-04-18 09:24:01 UTC
Size:
31.71 KB
patch
obsolete
>From 39df981b600e425eaef1272ca19e8426b4234830 Mon Sep 17 00:00:00 2001 >From: David Gustafsson <david.gustafsson@ub.gu.se> >Date: Fri, 13 Apr 2018 15:46:55 +0200 >Subject: [PATCH] Bug 20589: Add field boosting and use query_string fields > parameter > >Generate a list of fields for the query_string query fields parameter, >with possible boosts, instead of using "_all"-field. Also add "search" >flag in search_marc_to_field table so that certain mappings can be >excluded from searches. Add option to include/exclude fields in >query_string "fields" parameter depending on searching in OPAC or staff >client. Refactor code to remove all other dependencies on "_all"-field. > >How to test: >1) No reindex is really required, but still, reindex authorities and > biblios to verify that this still works. >2) Search biblios and try to verify that this works as expected. >3) Search authorities and try to verify that this works as expected. >4) Go to "Search engine configuration" >5) Change some "Boost", "Staff client", and "OPAC" settings and save. >6) Verify that those settings where saved accordingly. >7) Click the "Biblios" or "Authorities" tab and change one or more > "Searchable" settings >8) Verfiy that those settings where saved accordingly. >9) Try to verify that these settings has taken effect by peforming > some biblios and/or authorities searches. > >Sponsorded-by: Gothenburg Univesity Library >--- > Koha/Schema/Result/SearchField.pm | 6 + > Koha/Schema/Result/SearchMarcToField.pm | 2 + > Koha/SearchEngine/Elasticsearch.pm | 35 +++-- > Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 146 +++++++++++++++++---- > admin/searchengine/elasticsearch/mappings.pl | 74 ++++++++--- > .../mysql/atomicupdate/bug_20589_add_columns.perl | 17 +++ > .../admin/searchengine/elasticsearch/mappings.tt | 60 ++++++++- > opac/opac-search.pl | 2 +- > 8 files changed, 284 insertions(+), 58 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_20589_add_columns.perl > >diff --git a/Koha/Schema/Result/SearchField.pm b/Koha/Schema/Result/SearchField.pm >index ee32f42cf2..ac4f2aa073 100644 >--- a/Koha/Schema/Result/SearchField.pm >+++ b/Koha/Schema/Result/SearchField.pm >@@ -68,6 +68,12 @@ __PACKAGE__->add_columns( > extra => { list => ["", "string", "date", "number", "boolean", "sum"] }, > is_nullable => 0, > }, >+ "boost", >+ { data_type => "decimal", size => [ 5, 2 ], is_nullable => 1 }, >+ "staff_client", >+ { data_type => "tinyint", size => 1, is_nullable => 0, default => 1 }, >+ "opac", >+ { data_type => "tinyint", size => 1, is_nullable => 0, default => 1 }, > ); > > =head1 PRIMARY KEY >diff --git a/Koha/Schema/Result/SearchMarcToField.pm b/Koha/Schema/Result/SearchMarcToField.pm >index bfd27eab48..5f3ca053e9 100644 >--- a/Koha/Schema/Result/SearchMarcToField.pm >+++ b/Koha/Schema/Result/SearchMarcToField.pm >@@ -71,6 +71,8 @@ __PACKAGE__->add_columns( > { data_type => "tinyint", default_value => 0, is_nullable => 1 }, > "sort", > { data_type => "tinyint", is_nullable => 1 }, >+ "search", >+ { data_type => "tinyint", size => 1, is_nullable => 0, default => 1 }, > ); > > =head1 PRIMARY KEY >diff --git a/Koha/SearchEngine/Elasticsearch.pm b/Koha/SearchEngine/Elasticsearch.pm >index d859a39362..268f6825e7 100644 >--- a/Koha/SearchEngine/Elasticsearch.pm >+++ b/Koha/SearchEngine/Elasticsearch.pm >@@ -173,11 +173,9 @@ sub get_elasticsearch_mappings { > # TODO cache in the object? > my $mappings = { > data => { >- _all => {type => "string", analyzer => "analyser_standard"}, > properties => { > record => { > store => "true", >- include_in_all => JSON::false, > type => "text", > }, > } >@@ -187,7 +185,7 @@ sub get_elasticsearch_mappings { > my $marcflavour = lc C4::Context->preference('marcflavour'); > $self->_foreach_mapping( > sub { >- my ( $name, $type, $facet, $suggestible, $sort, $marc_type ) = @_; >+ my ( $name, $type, $facet, $suggestible, $sort, $search, $marc_type ) = @_; > return if $marc_type ne $marcflavour; > # TODO if this gets any sort of complexity to it, it should > # be broken out into its own function. >@@ -199,13 +197,16 @@ sub get_elasticsearch_mappings { > ? 'boolean' > : 'text'; > >+ if ($search) { >+ if ($es_type eq 'boolean') { >+ $mappings->{data}{properties}{$name} = _elasticsearch_mapping_for_boolean( $name, $es_type, $facet, $suggestible, $sort, $search, $marc_type ); >+ } else { >+ $mappings->{data}{properties}{$name} = _elasticsearch_mapping_for_default( $name, $es_type, $facet, $suggestible, $sort, $search, $marc_type ); >+ } >+ } > if ($es_type eq 'boolean') { >- $mappings->{data}{properties}{$name} = _elasticsearch_mapping_for_boolean( $name, $es_type, $facet, $suggestible, $sort, $marc_type ); > return; #Boolean cannot have facets nor sorting nor suggestions >- } else { >- $mappings->{data}{properties}{$name} = _elasticsearch_mapping_for_default( $name, $es_type, $facet, $suggestible, $sort, $marc_type ); > } >- > if ($facet) { > $mappings->{data}{properties}{ $name . '__facet' } = { > type => "keyword", >@@ -226,7 +227,6 @@ sub get_elasticsearch_mappings { > search_analyzer => "analyser_phrase", > analyzer => "analyser_phrase", > type => "text", >- include_in_all => JSON::false, > fields => { > phrase => { > type => "keyword", >@@ -250,7 +250,7 @@ Receives the same parameters from the $self->_foreach_mapping() dispatcher > =cut > > sub _elasticsearch_mapping_for_boolean { >- my ( $name, $type, $facet, $suggestible, $sort, $marc_type ) = @_; >+ my ( $name, $type, $facet, $suggestible, $sort, $search, $marc_type ) = @_; > > return { > type => $type, >@@ -259,7 +259,7 @@ sub _elasticsearch_mapping_for_boolean { > } > > sub _elasticsearch_mapping_for_default { >- my ( $name, $type, $facet, $suggestible, $sort, $marc_type ) = @_; >+ my ( $name, $type, $facet, $suggestible, $sort, $search, $marc_type ) = @_; > > return { > search_analyzer => "analyser_standard", >@@ -286,11 +286,13 @@ sub reset_elasticsearch_mappings { > while ( my ( $field_name, $data ) = each %$fields ) { > my $field_type = $data->{type}; > my $field_label = $data->{label}; >+ my $staff_client = exists $data->{staff_client} ? $data->{staff_client} : 1; >+ my $opac = exists $data->{opac} ? $data->{opac} : 1; > my $mappings = $data->{mappings}; >- my $search_field = Koha::SearchFields->find_or_create({ name => $field_name, label => $field_label, type => $field_type }, { key => 'name' }); >+ my $search_field = Koha::SearchFields->find_or_create({ name => $field_name, label => $field_label, type => $field_type, staff_client => $staff_client, opac => $opac }, { key => 'name' }); > for my $mapping ( @$mappings ) { > my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $mapping->{marc_type}, marc_field => $mapping->{marc_field} }); >- $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping->{facet} || 0, suggestible => $mapping->{suggestible} || 0, sort => $mapping->{sort} } ); >+ $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping->{facet} || 0, suggestible => $mapping->{suggestible} || 0, sort => $mapping->{sort}, search => $mapping->{search} || 1 } ); > } > } > } >@@ -321,7 +323,7 @@ sub get_fixer_rules { > > $self->_foreach_mapping( > sub { >- my ( $name, $type, $facet, $suggestible, $sort, $marc_type, $marc_field ) = @_; >+ my ( $name, $type, $facet, $suggestible, $sort, $search, $marc_type, $marc_field ) = @_; > return if $marc_type ne $marcflavour; > my $options = ''; > >@@ -330,7 +332,9 @@ sub get_fixer_rules { > # The split makes everything into nested arrays, but that's not > # really a big deal, ES doesn't mind. > $options = '-split => 1' unless $marc_field =~ m|_/| || $type eq 'sum'; >- push @rules, "marc_map('$marc_field','${name}.\$append', $options)"; >+ if ($search) { >+ push @rules, "marc_map('$marc_field','${name}.\$append', $options)"; >+ } > if ($facet) { > push @rules, "marc_map('$marc_field','${name}__facet.\$append', $options)"; > } >@@ -428,6 +432,7 @@ sub _foreach_mapping { > 'search_marc_to_fields.facet', > 'search_marc_to_fields.suggestible', > 'search_marc_to_fields.sort', >+ 'search_marc_to_fields.search', > 'search_marc_map.marc_type', > 'search_marc_map.marc_field', > ], >@@ -435,6 +440,7 @@ sub _foreach_mapping { > 'facet', > 'suggestible', > 'sort', >+ 'search', > 'marc_type', > 'marc_field', > ], >@@ -448,6 +454,7 @@ sub _foreach_mapping { > $search_field->get_column('facet'), > $search_field->get_column('suggestible'), > $search_field->get_column('sort'), >+ $search_field->get_column('search'), > $search_field->get_column('marc_type'), > $search_field->get_column('marc_field'), > ); >diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm >index 95cc86ab78..2cf59ce456 100644 >--- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm >+++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm >@@ -48,6 +48,7 @@ use URI::Escape; > > use C4::Context; > use Koha::Exceptions; >+use Koha::Caches; > > =head2 build_query > >@@ -90,7 +91,7 @@ sub build_query { > query => $query, > fuzziness => $fuzzy_enabled ? 'auto' : '0', > default_operator => 'AND', >- default_field => '_all', >+ fields => $self->_query_string_fields({ is_opac => $options{is_opac} }), > lenient => JSON::true, > } > }; >@@ -233,6 +234,7 @@ sub build_query_compat { > my %options; > $options{sort} = \@sort_params; > $options{expanded_facet} = $params->{expanded_facet}; >+ $options{is_opac} = exists $params->{is_opac} ? $params->{is_opac} : 0; > my $query = $self->build_query( $query_str, %options ); > > #die Dumper($query); >@@ -293,16 +295,55 @@ sub build_authorities_query { > my @filter_parts; > foreach my $s ( @{ $search->{searches} } ) { > my ( $wh, $op, $val ) = @{$s}{qw(where operator value)}; >- $wh = '_all' if $wh eq ''; >- if ( $op eq 'is' || $op eq '=' ) { >- >+ if (!$wh) { >+ my %query_string_params = ( >+ default_operator => 'AND', >+ ); >+ if ( $op eq 'is' || $op eq '=' ) { >+ push @query_parts, { >+ multi_match => { >+ query => $val, >+ fields => $self->_query_string_fields({ subfield => 'raw' }), >+ } >+ }; >+ } >+ elsif ( $op eq 'exact' ) { >+ # left and right truncation, otherwise an exact phrase >+ push @query_parts, { >+ query_string => { >+ query => qq("$val"), >+ fields => $self->_query_string_fields({ subfield => 'phrase' }), >+ %query_string_params, >+ } >+ }; >+ } >+ elsif ( $op eq 'start') { >+ push @query_parts, { >+ query_string => { >+ query => "$val*", >+ $self->_query_string_fields({ subfield => 'phrase' }), >+ %query_string_params, >+ } >+ }; >+ } >+ else { >+ push @query_parts, { >+ query_string => { >+ query => $val, >+ fields => $self->_query_string_fields(), >+ %query_string_params, >+ } >+ }; >+ } >+ } >+ elsif ( $op eq 'is' || $op eq '=' ) { > # look for something that matches completely > # note, '=' is about numerical vals. May need special handling. >- # _allphrase is a special field that only groups the exact >+ # raw is a special subfield that only groups the exact > # matches. Also, we lowercase our search because the ES > # index lowercases its values, and term searches don't get the > # search analyzer applied to them. >- push @filter_parts, { term => { "$wh.phrase" => lc $val } }; >+ push @query_parts, { term => { "$wh.raw" => lc $val } }; > } > elsif ( $op eq 'exact' ) { > >@@ -320,13 +361,10 @@ sub build_authorities_query { > } > } > >- # Merge the query and filter parts appropriately >- # 'should' behaves like 'or', if we want 'and', use 'must' >- my $query_part = { bool => { should => \@query_parts } }; >- my $filter_part = { bool => { should => \@filter_parts } }; >- > # We need to add '.phrase' to all the sort headings otherwise it'll sort > # based on the tokenised form. >+ # TODO: .phrase currently contains the tokenized form, so this will not work >+ # instead .raw should be used? > my %s; > if ( exists $search->{sort} ) { > foreach my $k ( keys %{ $search->{sort} } ) { >@@ -339,21 +377,24 @@ sub build_authorities_query { > # extract the sort stuff > my %sort; > %sort = ( sort => [ $search->{sort} ] ) if exists $search->{sort}; >- my $query; >+ >+ # Merge the query and filter parts appropriately >+ # 'should' behaves like 'or', if we want 'and', use 'must' >+ my $elastic_query = {}; > if (@filter_parts) { >- $query = >- { query => >- { filtered => { filter => $filter_part, query => $query_part } } >- }; >- } >- else { >- $query = { query => $query_part }; >+ $elastic_query->{bool}->{filter} = { >+ bool => { >+ must => \@filter_parts, >+ } >+ }; > } >- $query = { %$query, %sort }; >- return $query; >+ if (@query_parts) { >+ $elastic_query->{bool}->{should} = \@query_parts; >+ }; >+ my $params = { query => $elastic_query }; >+ return { %$params, %sort }; > } > >- > =head2 build_authorities_query_compat > > my ($query) = >@@ -513,7 +554,7 @@ types. > =cut > > our %index_field_convert = ( >- 'kw' => '_all', >+ 'kw' => '', > 'ti' => 'title', > 'au' => 'author', > 'su' => 'subject', >@@ -539,7 +580,7 @@ sub _convert_index_fields { > # If a field starts with mc- we save it as it's used (and removed) later > # when joining things, to indicate we make it an 'OR' join. > # (Sorry, this got a bit ugly after special cases were found.) >- grep { $_->{field} } map { >+ map { > my ( $f, $t ) = split /,/; > my $mc = ''; > if ($f =~ /^mc-/) { >@@ -551,7 +592,7 @@ sub _convert_index_fields { > type => $index_type_convert{ $t // '__default' } > }; > $r->{field} = ($mc . $r->{field}) if $mc && $r->{field}; >- $r; >+ $r->{field} ? $r : undef; > } @indexes; > } > >@@ -580,8 +621,8 @@ sub _convert_index_strings { > push @res, $s; > next; > } >- push @res, $conv->{field} . ":" >- . $self->_modify_string_by_type( %$conv, operand => $term ); >+ push @res, ($conv->{field} ? $conv->{field} . ':' : '') >+ . $self->_modify_string_by_type( %$conv, operand => $term ); > } > return @res; > } >@@ -813,4 +854,55 @@ sub _truncate_terms { > return join ' ', @terms; > } > >+sub _query_string_fields { >+ my ($self, $params) = @_; >+ $params //= { >+ is_opac => 0, >+ # This is a terrible hack for authorities build_authorities_query >+ # can hopefully be removed in the future >+ subfield => undef, >+ }; >+ >+ my $cache = Koha::Caches->get_instance(); >+ my $cache_key = 'elasticsearch_search_fields' . ($params->{is_opac} ? '_opac' : '_staff_client'); >+ my $search_fields = $cache->get_from_cache($cache_key, { unsafe => 1 }); >+ >+ if (!$search_fields) { >+ my $schema = Koha::Database->schema; >+ my $result = $schema->resultset('SearchField')->search( >+ { >+ $params->{is_opac} ? ( >+ 'opac' => 1, >+ ) : ( >+ 'staff_client' => 1 >+ ), >+ 'search_marc_map.index_name' => $self->index, >+ 'search_marc_map.marc_type' => C4::Context->preference('marcflavour'), >+ 'search_marc_to_fields.search' => 1, >+ }, >+ { >+ collapse => 1, >+ join => {search_marc_to_fields => 'search_marc_map'}, >+ } >+ ); >+ my @search_fields; >+ while (my $search_field = $result->next) { >+ push @search_fields, $search_field->name . >+ ($search_field->boost ? '^' . $search_field->boost : ''); >+ } >+ $search_fields = \@search_fields; >+ $cache->set_in_cache($cache_key, $search_fields); >+ } >+ if ($params->{subfield}) { >+ my $subfield = $params->{subfield}; >+ $search_fields = [ >+ map { >+ my ($field, $boost) = $_ =~ /^([^\^]+)(?:\^(.+))?$/; >+ "${field}.${subfield}" . ($boost ? "^$boost" : ''); >+ } @{$search_fields} >+ ]; >+ } >+ return $search_fields; >+} >+ > 1; >diff --git a/admin/searchengine/elasticsearch/mappings.pl b/admin/searchengine/elasticsearch/mappings.pl >index 7d63002919..72f0fa200a 100755 >--- a/admin/searchengine/elasticsearch/mappings.pl >+++ b/admin/searchengine/elasticsearch/mappings.pl >@@ -16,6 +16,7 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >+use Scalar::Util qw(looks_like_number); > use CGI; > use C4::Koha; > use C4::Output; >@@ -24,6 +25,7 @@ use C4::Auth; > use Koha::SearchEngine::Elasticsearch; > use Koha::SearchMarcMaps; > use Koha::SearchFields; >+use Koha::Caches; > > my $input = new CGI; > my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >@@ -44,6 +46,12 @@ my $schema = $database->schema; > > my $marc_type = lc C4::Context->preference('marcflavour'); > >+my $cache = Koha::Caches->get_instance(); >+my $clear_cache = sub { >+ $cache->clear_from_cache('elasticsearch_search_fields_staff_client'); >+ $cache->clear_from_cache('elasticsearch_search_fields_opac'); >+}; >+ > if ( $op eq 'edit' ) { > > $schema->storage->txn_begin; >@@ -51,12 +59,16 @@ if ( $op eq 'edit' ) { > my @field_name = $input->param('search_field_name'); > my @field_label = $input->param('search_field_label'); > my @field_type = $input->param('search_field_type'); >+ my @field_boost = $input->param('search_field_boost'); >+ my @field_staff_client = $input->param('search_field_staff_client'); >+ my @field_opac = $input->param('search_field_opac'); > > my @index_name = $input->param('mapping_index_name'); >- my @search_field_name = $input->param('mapping_search_field_name'); >+ my @search_field_name = $input->param('mapping_search_field_name'); > my @mapping_sort = $input->param('mapping_sort'); > my @mapping_facet = $input->param('mapping_facet'); > my @mapping_suggestible = $input->param('mapping_suggestible'); >+ my @mapping_search = $input->param('mapping_search'); > my @mapping_marc_field = $input->param('mapping_marc_field'); > > eval { >@@ -65,9 +77,15 @@ if ( $op eq 'edit' ) { > my $field_name = $field_name[$i]; > my $field_label = $field_label[$i]; > my $field_type = $field_type[$i]; >+ my $field_boost = $field_boost[$i]; >+ my $field_staff_client = $field_staff_client[$i]; >+ my $field_opac = $field_opac[$i]; > my $search_field = Koha::SearchFields->find( { name => $field_name }, { key => 'name' } ); > $search_field->label($field_label); > $search_field->type($field_type); >+ $search_field->boost($field_boost) if looks_like_number($field_boost); >+ $search_field->staff_client($field_staff_client ? 1 : 0); >+ $search_field->opac($field_opac ? 1 : 0); > $search_field->store; > } > >@@ -75,18 +93,26 @@ if ( $op eq 'edit' ) { > > for my $i ( 0 .. scalar(@index_name) - 1 ) { > my $index_name = $index_name[$i]; >- my $search_field_name = $search_field_name[$i]; >+ my $search_field_name = $search_field_name[$i]; > my $mapping_marc_field = $mapping_marc_field[$i]; > my $mapping_facet = $mapping_facet[$i]; > my $mapping_suggestible = $mapping_suggestible[$i]; >- my $mapping_sort = $mapping_sort[$i]; >- $mapping_sort = undef if $mapping_sort eq 'undef'; >+ my $mapping_sort = $mapping_sort[$i] eq 'undef' ? undef : $mapping_sort[$i]; >+ my $mapping_search = $mapping_search[$i]; > > my $search_field = Koha::SearchFields->find({ name => $search_field_name }, { key => 'name' }); > # TODO Check mapping format >- my $marc_field = Koha::SearchMarcMaps->find_or_create({ index_name => $index_name, marc_type => $marc_type, marc_field => $mapping_marc_field }); >- $search_field->add_to_search_marc_maps($marc_field, { facet => $mapping_facet, suggestible => $mapping_suggestible, sort => $mapping_sort } ); >- >+ my $marc_field = Koha::SearchMarcMaps->find_or_create({ >+ index_name => $index_name, >+ marc_type => $marc_type, >+ marc_field => $mapping_marc_field >+ }); >+ $search_field->add_to_search_marc_maps($marc_field, { >+ facet => $mapping_facet, >+ suggestible => $mapping_suggestible, >+ sort => $mapping_sort, >+ search => $mapping_search, >+ }); > } > }; > if ($@) { >@@ -96,6 +122,7 @@ if ( $op eq 'edit' ) { > push @messages, { type => 'message', code => 'success_on_update' }; > $schema->storage->txn_commit; > } >+ $clear_cache->(); > } > elsif( $op eq 'reset' ) { > # TODO Move this feature to the interface >@@ -104,32 +131,49 @@ elsif( $op eq 'reset' ) { > Koha::SearchMarcMaps->search->delete; > Koha::SearchEngine::Elasticsearch->reset_elasticsearch_mappings; > } >+ $clear_cache->(); > } > > my @indexes; > > for my $index_name (qw| biblios authorities |) { > my $search_fields = Koha::SearchFields->search( >- { 'search_marc_map.index_name' => $index_name, 'search_marc_map.marc_type' => $marc_type, }, >- { join => { search_marc_to_fields => 'search_marc_map' }, >- '+select' => [ 'search_marc_to_fields.facet', 'search_marc_to_fields.suggestible', 'search_marc_to_fields.sort', 'search_marc_map.marc_field' ], >- '+as' => [ 'facet', 'suggestible', 'sort', 'marc_field' ], >+ { >+ 'search_marc_map.index_name' => $index_name, >+ 'search_marc_map.marc_type' => $marc_type, >+ }, >+ { >+ join => { search_marc_to_fields => 'search_marc_map' }, >+ '+select' => [ >+ 'search_marc_to_fields.facet', >+ 'search_marc_to_fields.suggestible', >+ 'search_marc_to_fields.sort', >+ 'search_marc_to_fields.search', >+ 'search_marc_map.marc_field', >+ ], >+ '+as' => [ >+ 'facet', >+ 'suggestible', >+ 'sort', >+ 'search', >+ 'marc_field', >+ ], > } > ); > > my @mappings; > while ( my $s = $search_fields->next ) { >- push @mappings, >- { search_field_name => $s->name, >+ push @mappings, { >+ search_field_name => $s->name, > search_field_label => $s->label, > search_field_type => $s->type, > marc_field => $s->get_column('marc_field'), > sort => $s->get_column('sort') // 'undef', # To avoid warnings "Use of uninitialized value in lc" > suggestible => $s->get_column('suggestible'), > facet => $s->get_column('facet'), >- }; >+ search => $s->get_column('search'), >+ }; > } >- > push @indexes, { index_name => $index_name, mappings => \@mappings }; > } > >diff --git a/installer/data/mysql/atomicupdate/bug_20589_add_columns.perl b/installer/data/mysql/atomicupdate/bug_20589_add_columns.perl >new file mode 100644 >index 0000000000..195674a49e >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_20589_add_columns.perl >@@ -0,0 +1,17 @@ >+$DBversion = 'XXX'; >+if (CheckVersion($DBversion)) { >+ if (!column_exists('search_marc_to_field', 'search')) { >+ $dbh->do("ALTER TABLE `search_marc_to_field` ADD COLUMN `search` tinyint(1) NOT NULL DEFAULT 1"); >+ } >+ if (!column_exists('search_field', 'boost')) { >+ $dbh->do("ALTER TABLE `search_field` ADD COLUMN `boost` decimal(5,2) DEFAULT NULL"); >+ } >+ if (!column_exists('search_field', 'staff_client')) { >+ $dbh->do("ALTER TABLE `search_field` ADD COLUMN `staff_client` tinyint(1) NOT NULL DEFAULT 1"); >+ } >+ if (!column_exists('search_field', 'opac')) { >+ $dbh->do("ALTER TABLE `search_field` ADD COLUMN `opac` tinyint(1) NOT NULL DEFAULT 1"); >+ } >+ SetVersion($DBversion) >+} >+print "Upgrade to $DBversion done (Bug 20589 - Add field boosting and use elastic query fields parameter instead of depricated _all)\n"; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >index 25535d9c2c..78558cc7f1 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/searchengine/elasticsearch/mappings.tt >@@ -126,6 +126,14 @@ a.add, a.delete { > <th>Name</th> > <th>Label</th> > <th>Type</th> >+ <th colspan="2">Searchable</th> >+ <th>Boost</th> >+ </tr> >+ <tr> >+ <th colspan=3> </th> >+ <th>Staff client</th> >+ <th>OPAC</th> >+ <th> </th> > </tr> > </thead> > <tbody> >@@ -134,7 +142,9 @@ a.add, a.delete { > <td> > <input type="text" name="search_field_name" value="[% search_field.name %]" /> > </td> >- <td><input type="text" name="search_field_label" value="[% search_field.label %]" /> >+ <td> >+ <input type="text" name="search_field_label" value="[% search_field.label %]" /> >+ </td> > <td> > <select name="search_field_type"> > <option value=""></option> >@@ -165,6 +175,31 @@ a.add, a.delete { > [% END %] > </select> > </td> >+ <td> >+ <select name="search_field_staff_client"> >+ [% IF search_field.staff_client %] >+ <option value="1" selected="selected">Yes</option> >+ <option value="0">No</option> >+ [% ELSE %] >+ <option value="1">Yes</option> >+ <option value="0" selected="selected">No</option> >+ [% END %] >+ </select> >+ </td> >+ <td> >+ <select name="search_field_opac"> >+ [% IF search_field.opac %] >+ <option value="1" selected="selected">Yes</option> >+ <option value="0">No</option> >+ [% ELSE %] >+ <option value="1">Yes</option> >+ <option value="0" selected="selected">No</option> >+ [% END %] >+ </select> >+ </td> >+ <td> >+ <input type="text" size="3" name="search_field_boost" value="[% search_field.boost %]" /> >+ </td> > </tr> > [% END %] > </tbody> >@@ -179,6 +214,7 @@ a.add, a.delete { > <th>Sortable</th> > <th>Facetable</th> > <th>Suggestible</th> >+ <th>Searchable</th> > <th>Mapping</th> > <th></th> > </tr> >@@ -233,6 +269,17 @@ a.add, a.delete { > </select> > </td> > <td> >+ <select name="mapping_search"> >+ [% IF mapping.search %] >+ <option value="0">No</option> >+ <option value="1" selected="selected">Yes</option> >+ [% ELSE %] >+ <option value="0" selected="selected">No</option> >+ <option value="1">Yes</option> >+ [% END %] >+ </select> >+ </td> >+ <td> > <input name="mapping_marc_field" type="text" value="[% mapping.marc_field %]" /> > </td> > <td><a class="btn btn-default btn-xs delete" style="cursor: pointer;"><i class="fa fa-trash"></i> Delete</a></td> >@@ -278,6 +325,17 @@ a.add, a.delete { > [% END %] > </select> > </td> >+ <td> >+ <select data-id="mapping_search"> >+ [% IF mapping.search %] >+ <option value="0">No</option> >+ <option value="1" selected="selected">Yes</option> >+ [% ELSE %] >+ <option value="0" selected="selected">No</option> >+ <option value="1">Yes</option> >+ [% END %] >+ </select> >+ </td> > <td><input data-id="mapping_marc_field" type="text" /></td> > <td><a class="btn btn-default btn-xs add"><i class="fa fa-plus"></i> Add</a></td> > </tr> >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index ccde617022..bc3376cb4c 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -555,7 +555,7 @@ if (C4::Context->preference('OpacSuppression')) { > \@sort_by, > 0, > $lang, >- { expanded_facet => $expanded_facet, suppress => $suppress } >+ { expanded_facet => $expanded_facet, suppress => $suppress, is_opac => 1 } > ); > > sub _input_cgi_parse { >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 20589
:
74245
|
74249
|
74301
|
74373
|
74418
|
74419
|
82503
|
82544
|
83016
|
83019
|
87358
|
87411
|
87412
|
87415
|
87416
|
92454
|
92455
|
92456
|
92457
|
93238
|
93239
|
93240
|
93241
|
93247
|
93248
|
93249
|
93250
|
93251
|
93348
|
93349
|
93350
|
93351
|
93352
|
93353
|
93379
|
93380
|
93381
|
93382
|
93383
|
93384
|
93590
|
93624