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

(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-30 / +25 lines)
Lines 290-329 sub build_authorities_query { Link Here
290
290
291
    # Start by making the query parts
291
    # Start by making the query parts
292
    my @query_parts;
292
    my @query_parts;
293
    my @filter_parts;
293
294
    foreach my $s ( @{ $search->{searches} } ) {
294
    foreach my $s ( @{ $search->{searches} } ) {
295
        my ( $wh, $op, $val ) = @{$s}{qw(where operator value)};
295
        my ( $wh, $op, $val ) = @{$s}{qw(where operator value)};
296
        $wh = '_all' if $wh eq '';
296
        $wh = '_all' if $wh eq '';
297
        if ( $op eq 'is' || $op eq '=' ) {
297
        if ( $op eq 'is' || $op eq '=' ) {
298
298
299
            # look for something that matches completely
299
            # look for something that matches a term completely
300
            # note, '=' is about numerical vals. May need special handling.
300
            # note, '=' is about numerical vals. May need special handling.
301
            # _allphrase is a special field that only groups the exact
301
            # Also, we lowercase our search because the ES
302
            # matches. Also, we lowercase our search because the ES
303
            # index lowercases its values, and term searches don't get the
302
            # index lowercases its values, and term searches don't get the
304
            # search analyzer applied to them.
303
            # search analyzer applied to them.
305
            push @filter_parts, { term => { "$wh.phrase" => lc $val } };
304
            push @query_parts, { term => {"$wh.phrase" => lc $val} };
306
        }
305
        }
307
        elsif ( $op eq 'exact' ) {
306
        elsif ( $op eq 'exact' ) {
308
309
            # left and right truncation, otherwise an exact phrase
307
            # left and right truncation, otherwise an exact phrase
310
            push @query_parts, { match_phrase => { $wh => $val } };
308
            push @query_parts, { match_phrase => {"$wh.phrase" => lc $val} };
311
        }
309
        }
312
        elsif ( $op eq 'start' ) {
310
        elsif ( $op eq 'start' ) {
313
311
            # startswith search, uses lowercase untokenized version of heading
314
            # startswith search
312
            push @query_parts, { prefix => {"$wh.lc_raw" => lc $val} };
315
            push @query_parts, { wildcard => { "$wh.phrase" => lc "$val*" } };
316
        }
313
        }
317
        else {
314
        else {
318
            # regular wordlist stuff
315
            # regular wordlist stuff
319
            push @query_parts, { match => { $wh => $val } };
316
#            push @query_parts, { match => {$wh => { query => $val, operator => 'and' }} };
317
            my @values = split(' ',$val);
318
            foreach $val (@values) {
319
                push @query_parts, { wildcard => { "$wh.phrase" => "*" . lc $val . "*" } };
320
            }
320
        }
321
        }
321
    }
322
    }
322
323
323
    # Merge the query and filter parts appropriately
324
    # Merge the query parts appropriately
324
    # 'should' behaves like 'or', if we want 'and', use 'must'
325
    # 'should' behaves like 'or'
325
    my $query_part  = { bool => { should => \@query_parts } };
326
    # 'must' behaves like 'and'
326
    my $filter_part = { bool => { should => \@filter_parts } };
327
    # Zebra results seem to match must so using that here
328
    my $query = { query=>
329
                 { bool =>
330
                     { must => \@query_parts  }
331
                 }
332
             };
327
333
328
    # We need to add '.phrase' to all the sort headings otherwise it'll sort
334
    # We need to add '.phrase' to all the sort headings otherwise it'll sort
329
    # based on the tokenised form.
335
    # based on the tokenised form.
Lines 336-355 sub build_authorities_query { Link Here
336
        $search->{sort} = \%s;
342
        $search->{sort} = \%s;
337
    }
343
    }
338
344
339
    # extract the sort stuff
345
    # add the sort stuff
340
    my %sort;
346
    $query->{sort} = [ $search->{sort} ]  if exists $search->{sort};
341
    %sort = ( sort => [ $search->{sort} ] ) if exists $search->{sort};
347
342
    my $query;
343
    if (@filter_parts) {
344
        $query =
345
          { query =>
346
              { filtered => { filter => $filter_part, query => $query_part } }
347
          };
348
    }
349
    else {
350
        $query = { query => $query_part };
351
    }
352
    $query = { %$query, %sort };
353
    return $query;
348
    return $query;
354
}
349
}
355
350
Lines 446-452 sub build_authorities_query_compat { Link Here
446
441
447
    my %sort;
442
    my %sort;
448
    my $sort_field =
443
    my $sort_field =
449
        ( $orderby =~ /^Heading/ ) ? 'Heading'
444
        ( $orderby =~ /^Heading/ ) ? 'Heading__sort'
450
      : ( $orderby =~ /^Auth/ )    ? 'Local-Number'
445
      : ( $orderby =~ /^Auth/ )    ? 'Local-Number'
451
      :                              undef;
446
      :                              undef;
452
    if ($sort_field) {
447
    if ($sort_field) {
(-)a/admin/searchengine/elasticsearch/field_config.yaml (+3 lines)
Lines 39-44 search: Link Here
39
        search_analyzer: analyser_phrase
39
        search_analyzer: analyser_phrase
40
      raw:
40
      raw:
41
        type: keyword
41
        type: keyword
42
      lc_raw:
43
        type: keyword
44
        normalizer: my_normalizer
42
    copy_to: _all
45
    copy_to: _all
43
# Facets
46
# Facets
44
facet:
47
facet:
(-)a/admin/searchengine/elasticsearch/index_config.yaml (-1 / +3 lines)
Lines 25-30 index: Link Here
25
        type: custom
25
        type: custom
26
        filter:
26
        filter:
27
          - icu_folding
27
          - icu_folding
28
      my_normalizer:
29
        type: custom
30
        char_filter: icu_normalizer
28
    char_filter:
31
    char_filter:
29
      # The punctuation filter is used to remove any punctuation chars in fields that don't use icu_tokenizer.
32
      # The punctuation filter is used to remove any punctuation chars in fields that don't use icu_tokenizer.
30
      punctuation:
33
      punctuation:
31
- 

Return to bug 19604