View | Details | Raw Unified | Return to bug 38694
Collapse All | Expand All

(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-16 / +47 lines)
Lines 203-219 sub build_query { Link Here
203
    if ( $options{whole_record} ) {
203
    if ( $options{whole_record} ) {
204
        push @$fields, 'marc_data_array.*';
204
        push @$fields, 'marc_data_array.*';
205
    }
205
    }
206
    $res->{query} = {
206
    my $query_string = {
207
        query_string => {
207
        query            => $query,
208
            query            => $query,
208
        fuzziness        => $fuzzy_enabled ? 'auto' : '0',
209
            fuzziness        => $fuzzy_enabled ? 'auto' : '0',
209
        default_operator => 'AND',
210
            default_operator => 'AND',
210
        fields           => $fields,
211
            fields           => $fields,
211
        lenient          => JSON::true,
212
            lenient          => JSON::true,
212
        analyze_wildcard => JSON::true,
213
            analyze_wildcard => JSON::true,
214
        }
215
    };
213
    };
216
    $res->{query}->{query_string}->{type} = 'cross_fields' if C4::Context->preference('ElasticsearchCrossFields');
214
    $query_string->{type} = 'cross_fields' if C4::Context->preference('ElasticsearchCrossFields');
215
216
    $res->{query} = { bool => { must => [ { query_string => $query_string } ] } };
217
218
    $res->{query}->{bool}->{should} = $options{field_match_boost_query} if $options{field_match_boost_query};
217
219
218
    if ( $options{sort} ) {
220
    if ( $options{sort} ) {
219
        foreach my $sort ( @{ $options{sort} } ) {
221
        foreach my $sort ( @{ $options{sort} } ) {
Lines 280-285 sub build_query_compat { Link Here
280
    } else {
282
    } else {
281
        my @sort_params  = $self->_convert_sort_fields(@$sort_by);
283
        my @sort_params  = $self->_convert_sort_fields(@$sort_by);
282
        my @index_params = $self->_convert_index_fields(@$indexes);
284
        my @index_params = $self->_convert_index_fields(@$indexes);
285
        my $field_match_boost_query =
286
            C4::Context->preference('ESBoostFieldMatch')
287
            ? $self->_build_field_match_boost_query( { operands => $operands, indexes => \@index_params } )
288
            : [];
283
        $limits = $self->_fix_limit_special_cases($orig_limits);
289
        $limits = $self->_fix_limit_special_cases($orig_limits);
284
        if ( $params->{suppress} ) { push @$limits, "suppress:false"; }
290
        if ( $params->{suppress} ) { push @$limits, "suppress:false"; }
285
291
Lines 320-331 sub build_query_compat { Link Here
320
        # If there's no query on the left, let's remove the junk left behind
326
        # If there's no query on the left, let's remove the junk left behind
321
        $query_str =~ s/^ AND //;
327
        $query_str =~ s/^ AND //;
322
        my %options;
328
        my %options;
323
        $options{sort}            = \@sort_params;
329
        $options{sort}                    = \@sort_params;
324
        $options{is_opac}         = $params->{is_opac};
330
        $options{is_opac}                 = $params->{is_opac};
325
        $options{weighted_fields} = $params->{weighted_fields};
331
        $options{weighted_fields}         = $params->{weighted_fields};
326
        $options{whole_record}    = $params->{whole_record};
332
        $options{whole_record}            = $params->{whole_record};
327
        $options{skip_facets}     = $params->{skip_facets};
333
        $options{skip_facets}             = $params->{skip_facets};
328
        $query                    = $self->build_query( $query_str, %options );
334
        $options{field_match_boost_query} = $field_match_boost_query if @$field_match_boost_query;
335
        $query                            = $self->build_query( $query_str, %options );
329
    }
336
    }
330
337
331
    # We roughly emulate the CGI parameters of the zebra query builder
338
    # We roughly emulate the CGI parameters of the zebra query builder
Lines 361-366 sub build_query_compat { Link Here
361
    );
368
    );
362
}
369
}
363
370
371
=head2 _build_field_match_boost_query
372
373
    my ($query, $query_str) = $builder->_build_field_match_boost_query({ operands => \@operands, indexes => \@indexes)
374
375
This will build an array of match queries for terms and indexes passed in and return a reference to the array.
376
377
=cut
378
379
sub _build_field_match_boost_query {
380
    my ( $self, $params ) = @_;
381
    my $indexes  = $params->{indexes};
382
    my $operands = $params->{operands};
383
384
    my @boost_query;
385
    my $ea = each_array( @$operands, @$indexes );
386
    while ( my ( $operand, $index ) = $ea->() ) {
387
        next unless $operand;
388
        $index = $index->{field} if ref $index eq 'HASH';
389
        $index = 'title-cover'   if ( !$index || $index eq 'kw' || $index eq 'ti' || $index eq 'title' );
390
        push @boost_query, { match => { $index => { query => $operand } } };
391
    }
392
    return \@boost_query;
393
}
394
364
=head2 build_authorities_query
395
=head2 build_authorities_query
365
396
366
    my $query = $builder->build_authorities_query(\%search);
397
    my $query = $builder->build_authorities_query(\%search);
(-)a/installer/data/mysql/atomicupdate/bug38694.pl (+21 lines)
Line 0 Link Here
1
use Modern::Perl;
2
use Koha::Installer::Output qw(say_warning say_success say_info);
3
4
return {
5
    bug_number  => "38694",
6
    description => "Add ESBoostFieldMatch system preference",
7
    up          => sub {
8
        my ($args) = @_;
9
        my ( $dbh, $out ) = @$args{qw(dbh out)};
10
11
        # Do you stuffs here
12
        $dbh->do(
13
            q{
14
           INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
15
           ('ESBoostFieldMatch', '0', NULL, 'Add a "match" query to es when searching, will follow indexes chosen in advanced search, or use title-cover for generic keyword or title index search', 'YesNo')
16
       }
17
        );
18
19
        say_success( $out, "Added new system preference 'ESBoostFieldMatch'" );
20
    },
21
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 260-265 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
260
('ERMProviderEbscoApiKey', '', '', 'API key for EBSCO', 'free'),
260
('ERMProviderEbscoApiKey', '', '', 'API key for EBSCO', 'free'),
261
('ERMProviderEbscoCustomerID', '', '', 'Customer ID for EBSCO', 'free'),
261
('ERMProviderEbscoCustomerID', '', '', 'Customer ID for EBSCO', 'free'),
262
('ERMProviders', 'local', 'local|ebsco', 'Set the providers for the ERM module', 'Choice'),
262
('ERMProviders', 'local', 'local|ebsco', 'Set the providers for the ERM module', 'Choice'),
263
('ESBoostFieldMatch', '0', NULL, 'Add a "match" query to es when searching, will follow indexes chosen in advanced search, or use title-cover for generic keyword or title index search', 'YesNo'),
263
('ESPreventAutoTruncate', 'barcode|control-number|control-number-identifier|date-of-acquisition|date-of-publication|date-time-last-modified|identifier-standard|isbn|issn|itype|lc-card-number|number-local-acquisition|other-control-number|record-control-number', NULL, 'List of searchfields (separated by | or ,) that should not be autotruncated by Elasticsearch even if QueryAutoTruncate is set to Yes', 'free'),
264
('ESPreventAutoTruncate', 'barcode|control-number|control-number-identifier|date-of-acquisition|date-of-publication|date-time-last-modified|identifier-standard|isbn|issn|itype|lc-card-number|number-local-acquisition|other-control-number|record-control-number', NULL, 'List of searchfields (separated by | or ,) that should not be autotruncated by Elasticsearch even if QueryAutoTruncate is set to Yes', 'free'),
264
('ExcludeHolidaysFromMaxPickUpDelay', '0', NULL, 'If ON, reserves max pickup delay takes into accountthe closed days.', 'YesNo'),
265
('ExcludeHolidaysFromMaxPickUpDelay', '0', NULL, 'If ON, reserves max pickup delay takes into accountthe closed days.', 'YesNo'),
265
('expandedSearchOption','0',NULL,'If ON, set advanced search to be expanded by default','YesNo'),
266
('expandedSearchOption','0',NULL,'If ON, set advanced search to be expanded by default','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref (-1 / +8 lines)
Lines 95-100 Searching: Link Here
95
                  0: Disable
95
                  0: Disable
96
            - "the cross_fields option for Elasticsearch searches, supported in Elasticsearch 6.X and above."
96
            - "the cross_fields option for Elasticsearch searches, supported in Elasticsearch 6.X and above."
97
            - See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#type-cross-fields">Elasticsearch cross_fields documentation</a>.
97
            - See the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html#type-cross-fields">Elasticsearch cross_fields documentation</a>.
98
        -
99
            - pref: ESBoostFieldMatch
100
              default: 0
101
              choices:
102
                  1: Enable
103
                  0: Disable
104
            - "adding a second 'match' field search to the ES query to boost relevancy. Keyword and title fields will be boosted with title-cover, other fields will boost directly."
105
            - "This will not boost CCL style searches, only standard or advanced searches"
98
        -
106
        -
99
            - pref: SavedSearchFilters
107
            - pref: SavedSearchFilters
100
              default: 0
108
              default: 0
101
- 

Return to bug 38694