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

(-)a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm (-42 / +82 lines)
Lines 78-107 according to these values. Valid values for C<direction> are 'asc' and 'desc'. Link Here
78
sub build_query {
78
sub build_query {
79
    my ( $self, $query, %options ) = @_;
79
    my ( $self, $query, %options ) = @_;
80
80
81
    my $stemming         = C4::Context->preference("QueryStemming")        || 0;
81
    my $res = { query => $query };
82
    my $auto_truncation  = C4::Context->preference("QueryAutoTruncate")    || 0;
83
    my $fuzzy_enabled    = C4::Context->preference("QueryFuzzy")           || 0;
84
85
    $query = '*' unless defined $query;
86
87
    my $res;
88
    my $fields = $self->_search_fields({
89
        is_opac => $options{is_opac},
90
        weighted_fields => $options{weighted_fields},
91
    });
92
    if ($options{whole_record}) {
93
        push @$fields, 'marc_data_array.*';
94
    }
95
    $res->{query} = {
96
        query_string => {
97
            query            => $query,
98
            fuzziness        => $fuzzy_enabled ? 'auto' : '0',
99
            default_operator => 'AND',
100
            fields           => $fields,
101
            lenient          => JSON::true,
102
            analyze_wildcard => JSON::true,
103
        }
104
    };
105
82
106
    if ( $options{sort} ) {
83
    if ( $options{sort} ) {
107
        foreach my $sort ( @{ $options{sort} } ) {
84
        foreach my $sort ( @{ $options{sort} } ) {
Lines 195-217 sub build_query_compat { Link Here
195
            };
172
            };
196
        }
173
        }
197
174
198
        # We build a string query from limits and the queries. An alternative
175
        my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0;
199
        # would be to pass them separately into build_query and let it build
176
        my $default_fields = $self->_search_fields({
200
        # them into a structured ES query itself. Maybe later, though that'd be
177
            is_opac => $params->{is_opac},
201
        # more robust.
178
            weighted_fields => $params->{weighted_fields},
202
        $search_param_query_str = join( ' ', $self->_create_query_string(@search_params) );
179
        });
203
        $query_str = join( ' AND ',
180
        if ($params->{whole_record}) {
204
            $search_param_query_str || (),
181
            push @$default_fields, 'marc_data_array.*';
205
            $self->_join_queries( $self->_convert_index_strings(@$limits) ) || () );
182
        }
206
183
207
        # If there's no query on the left, let's remove the junk left behind
184
        my $es_query = {
208
        $query_str =~ s/^ AND //;
185
            bool => {
209
        my %options;
186
                minimum_should_match => 1,
210
        $options{sort} = \@sort_params;
187
                should => [
211
        $options{is_opac} = $params->{is_opac};
188
                    {
212
        $options{weighted_fields} = $params->{weighted_fields};
189
                        bool => {
213
        $options{whole_record} = $params->{whole_record};
190
                            must => [],
214
        $query = $self->build_query( $query_str, %options );
191
                            must_not => [],
192
                        },
193
                    }
194
                ],
195
            },
196
        };
197
198
        foreach my $search_param (@search_params) {
199
            my $operand = $search_param->{operand};
200
            my $operator = $search_param->{operator} // '';
201
            my $field = $search_param->{field};
202
203
            my @fields;
204
            if ($field) {
205
                @fields = ($field, "$field.lang_*");
206
            } else {
207
                @fields = @$default_fields;
208
            }
209
210
            my $qs = {
211
                query_string => {
212
                    query => $operand,
213
                    fuzziness => $fuzzy_enabled ? 'auto' : 0,
214
                    default_operator => 'AND',
215
                    fields => \@fields,
216
                    lenient => JSON::true,
217
                    analyze_wildcard => JSON::true,
218
                },
219
            };
220
221
            if ($operator eq 'OR') {
222
                push @{ $es_query->{bool}->{should} }, {
223
                    bool => {
224
                        must => [$qs],
225
                        must_not => [],
226
                    },
227
                };
228
            } elsif ($operator eq 'NOT') {
229
                push @{ $es_query->{bool}->{should}->[-1]->{bool}->{must_not} }, $qs;
230
            } else {
231
                push @{ $es_query->{bool}->{should}->[-1]->{bool}->{must} }, $qs;
232
            }
233
        }
234
235
        my $limit_query_string = $self->_join_queries($self->_convert_index_strings(@$limits));
236
        if ($limit_query_string) {
237
            $es_query->{bool}{filter} = {
238
                query_string => {
239
                    query => $limit_query_string,
240
                    default_operator => 'AND',
241
                    lenient => JSON::true,
242
                },
243
            };
244
        }
245
246
        $query = $self->build_query( $es_query, sort => \@sort_params );
215
    }
247
    }
216
248
217
    # We roughly emulate the CGI parameters of the zebra query builder
249
    # We roughly emulate the CGI parameters of the zebra query builder
Lines 1172-1181 sub _search_fields { Link Here
1172
                # Copy values to avoid mutating cached
1204
                # Copy values to avoid mutating cached
1173
                # data (since unsafe is used)
1205
                # data (since unsafe is used)
1174
                my ($field, $weight) = @{$_};
1206
                my ($field, $weight) = @{$_};
1175
                ["${field}.${subfield}", $weight];
1207
                ["${field}.${subfield}", $weight ? $weight : ()];
1176
            } @{$search_fields}
1208
            } @{$search_fields}
1177
        ];
1209
        ];
1210
    } else {
1211
        $search_fields = [
1212
            map {
1213
                my ($field, $weight) = @{$_};
1214
                $_, ["$field.lang_*", $weight // ()];
1215
            } @$search_fields
1216
        ];
1178
    }
1217
    }
1218
1179
    if ($params->{weighted_fields}) {
1219
    if ($params->{weighted_fields}) {
1180
        return [map { join('^', @{$_}) } @{$search_fields}];
1220
        return [map { join('^', @{$_}) } @{$search_fields}];
1181
    }
1221
    }
(-)a/admin/searchengine/elasticsearch/field_config.yaml (-1 / +6 lines)
Lines 50-55 search: Link Here
50
      ci_raw:
50
      ci_raw:
51
        type: keyword
51
        type: keyword
52
        normalizer: icu_folding_normalizer
52
        normalizer: icu_folding_normalizer
53
      lang_en:
54
        type: text
55
        analyzer: english
56
      lang_fr:
57
        type: text
58
        analyzer: french
53
# Facets
59
# Facets
54
facet:
60
facet:
55
  default:
61
  default:
56
- 

Return to bug 21357