Lines 186-213
according to these values. Valid values for C<direction> are 'asc' and 'desc'.
Link Here
|
186 |
sub build_query { |
186 |
sub build_query { |
187 |
my ( $self, $query, %options ) = @_; |
187 |
my ( $self, $query, %options ) = @_; |
188 |
|
188 |
|
189 |
my $stemming = C4::Context->preference("QueryStemming") || 0; |
189 |
my $stemming = C4::Context->preference("QueryStemming") || 0; |
190 |
my $auto_truncation = C4::Context->preference("QueryAutoTruncate") || 0; |
190 |
my $auto_truncation = C4::Context->preference("QueryAutoTruncate") || 0; |
191 |
my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0; |
191 |
my $fuzzy_enabled = C4::Context->preference("QueryFuzzy") || 0; |
192 |
|
192 |
|
193 |
$query = '*' unless defined $query; |
193 |
$query = '*' unless defined $query; |
194 |
|
194 |
|
195 |
my $res; |
195 |
my $res; |
196 |
my $fields = $self->_search_fields({ |
196 |
my $fields = $self->_search_fields( |
197 |
is_opac => $options{is_opac}, |
197 |
{ |
198 |
weighted_fields => $options{weighted_fields}, |
198 |
is_opac => $options{is_opac}, |
199 |
}); |
199 |
weighted_fields => $options{weighted_fields}, |
200 |
if ($options{whole_record}) { |
200 |
} |
|
|
201 |
); |
202 |
if ( $options{whole_record} ) { |
201 |
push @$fields, 'marc_data_array.*'; |
203 |
push @$fields, 'marc_data_array.*'; |
202 |
} |
204 |
} |
203 |
my $query_string = { |
205 |
my $query_string = { |
204 |
query => $query, |
206 |
query => $query, |
205 |
fuzziness => $fuzzy_enabled ? 'auto' : '0', |
207 |
fuzziness => $fuzzy_enabled ? 'auto' : '0', |
206 |
default_operator => 'AND', |
208 |
default_operator => 'AND', |
207 |
fields => $fields, |
209 |
fields => $fields, |
208 |
lenient => JSON::true, |
210 |
lenient => JSON::true, |
209 |
analyze_wildcard => JSON::true, |
211 |
analyze_wildcard => JSON::true, |
210 |
}; |
212 |
}; |
211 |
$query_string->{type} = 'cross_fields' if C4::Context->preference('ElasticsearchCrossFields'); |
213 |
$query_string->{type} = 'cross_fields' if C4::Context->preference('ElasticsearchCrossFields'); |
212 |
|
214 |
|
213 |
$res->{query} = { bool => { must => [ { query_string => $query_string } ] } }; |
215 |
$res->{query} = { bool => { must => [ { query_string => $query_string } ] } }; |
Lines 218-224
sub build_query {
Link Here
|
218 |
foreach my $sort ( @{ $options{sort} } ) { |
220 |
foreach my $sort ( @{ $options{sort} } ) { |
219 |
my ( $f, $d ) = @$sort{qw/ field direction /}; |
221 |
my ( $f, $d ) = @$sort{qw/ field direction /}; |
220 |
die "Invalid sort direction, $d" |
222 |
die "Invalid sort direction, $d" |
221 |
if $d && ( $d ne 'asc' && $d ne 'desc' ); |
223 |
if $d && ( $d ne 'asc' && $d ne 'desc' ); |
222 |
$d = 'asc' unless $d; |
224 |
$d = 'asc' unless $d; |
223 |
|
225 |
|
224 |
$f = $self->_sort_field($f); |
226 |
$f = $self->_sort_field($f); |
Lines 228-241
sub build_query {
Link Here
|
228 |
|
230 |
|
229 |
# See _convert_facets in Search.pm for how these get turned into |
231 |
# See _convert_facets in Search.pm for how these get turned into |
230 |
# things that Koha can use. |
232 |
# things that Koha can use. |
231 |
my $size = C4::Context->preference('FacetMaxCount'); |
233 |
my $size = C4::Context->preference('FacetMaxCount'); |
232 |
my @facets = Koha::SearchEngine::Elasticsearch->get_facet_fields; |
234 |
my @facets = Koha::SearchEngine::Elasticsearch->get_facet_fields; |
233 |
for my $f ( @facets ) { |
235 |
for my $f (@facets) { |
234 |
my $name = $f->name; |
236 |
my $name = $f->name; |
235 |
$res->{aggregations}->{$name} = { terms => { field => "${name}__facet" , size => $size } }; |
237 |
$res->{aggregations}->{$name} = { terms => { field => "${name}__facet", size => $size } }; |
236 |
}; |
238 |
} |
237 |
|
239 |
|
238 |
$res = _rebuild_to_es_advanced_query($res) if @$es_advanced_searches ; |
240 |
$res = _rebuild_to_es_advanced_query($res) if @$es_advanced_searches; |
239 |
return $res; |
241 |
return $res; |
240 |
} |
242 |
} |
241 |
|
243 |
|
Lines 260-276
reproduce this search, and C<$query_desc> set to something else.
Link Here
|
260 |
=cut |
262 |
=cut |
261 |
|
263 |
|
262 |
sub build_query_compat { |
264 |
sub build_query_compat { |
263 |
my ( $self, $operators, $operands, $indexes, $orig_limits, $sort_by, $scan, |
265 |
my ( |
264 |
$lang, $params ) |
266 |
$self, $operators, $operands, $indexes, $orig_limits, $sort_by, $scan, |
265 |
= @_; |
267 |
$lang, $params |
266 |
|
268 |
) = @_; |
267 |
|
269 |
|
268 |
my $query; |
270 |
my $query; |
269 |
my $query_str = ''; |
271 |
my $query_str = ''; |
270 |
my $search_param_query_str = ''; |
272 |
my $search_param_query_str = ''; |
271 |
my $limits = (); |
273 |
my $limits = (); |
272 |
if ( $scan ) { |
274 |
if ($scan) { |
273 |
($query, $query_str) = $self->_build_scan_query( $operands, $indexes ); |
275 |
( $query, $query_str ) = $self->_build_scan_query( $operands, $indexes ); |
274 |
$search_param_query_str = $query_str; |
276 |
$search_param_query_str = $query_str; |
275 |
} else { |
277 |
} else { |
276 |
my @sort_params = $self->_convert_sort_fields(@$sort_by); |
278 |
my @sort_params = $self->_convert_sort_fields(@$sort_by); |
Lines 281-299
sub build_query_compat {
Link Here
|
281 |
: []; |
283 |
: []; |
282 |
$limits = $self->_fix_limit_special_cases($orig_limits); |
284 |
$limits = $self->_fix_limit_special_cases($orig_limits); |
283 |
if ( $params->{suppress} ) { push @$limits, "suppress:false"; } |
285 |
if ( $params->{suppress} ) { push @$limits, "suppress:false"; } |
|
|
286 |
|
284 |
# Merge the indexes in with the search terms and the operands so that |
287 |
# Merge the indexes in with the search terms and the operands so that |
285 |
# each search thing is a handy unit. |
288 |
# each search thing is a handy unit. |
286 |
unshift @$operators, undef; # The first one can't have an op |
289 |
unshift @$operators, undef; # The first one can't have an op |
287 |
my @search_params; |
290 |
my @search_params; |
288 |
my $truncate = C4::Context->preference("QueryAutoTruncate") || 0; |
291 |
my $truncate = C4::Context->preference("QueryAutoTruncate") || 0; |
289 |
my $ea = each_array( @$operands, @$operators, @index_params ); |
292 |
my $ea = each_array( @$operands, @$operators, @index_params ); |
290 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
293 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
291 |
next if ( !defined($oand) || $oand eq '' ); |
294 |
next if ( !defined($oand) || $oand eq '' ); |
292 |
$oand = $self->clean_search_term($oand); |
295 |
$oand = $self->clean_search_term($oand); |
293 |
$oand = $self->_truncate_terms($oand) |
296 |
$oand = $self->_truncate_terms($oand) |
294 |
if $truncate && $self->_is_safe_to_auto_truncate( $index->{field}, $oand ); |
297 |
if $truncate && $self->_is_safe_to_auto_truncate( $index->{field}, $oand ); |
295 |
push @search_params, { |
298 |
push @search_params, { |
296 |
operand => $oand, # the search terms |
299 |
operand => $oand, # the search terms |
297 |
operator => defined($otor) ? uc $otor : undef, # AND and so on |
300 |
operator => defined($otor) ? uc $otor : undef, # AND and so on |
298 |
$index ? %$index : (), |
301 |
$index ? %$index : (), |
299 |
}; |
302 |
}; |
Lines 305-353
sub build_query_compat {
Link Here
|
305 |
# more robust. |
308 |
# more robust. |
306 |
my @search_param_query_array = $self->_create_query_string(@search_params); |
309 |
my @search_param_query_array = $self->_create_query_string(@search_params); |
307 |
$search_param_query_str = join( ' ', @search_param_query_array ); |
310 |
$search_param_query_str = join( ' ', @search_param_query_array ); |
308 |
my $search_param_limit_str = |
311 |
my $search_param_limit_str = $self->_join_queries( $self->_convert_index_strings(@$limits) ); |
309 |
$self->_join_queries( $self->_convert_index_strings(@$limits) ); |
|
|
310 |
if ( @search_param_query_array > 1 && $search_param_limit_str ) { |
312 |
if ( @search_param_query_array > 1 && $search_param_limit_str ) { |
311 |
$search_param_query_str = "($search_param_query_str)"; |
313 |
$search_param_query_str = "($search_param_query_str)"; |
312 |
} |
314 |
} |
313 |
$query_str = join( ' AND ', |
315 |
$query_str = join( |
|
|
316 |
' AND ', |
314 |
$search_param_query_str || (), |
317 |
$search_param_query_str || (), |
315 |
$search_param_limit_str || () ); |
318 |
$search_param_limit_str || () |
|
|
319 |
); |
316 |
|
320 |
|
317 |
# If there's no query on the left, let's remove the junk left behind |
321 |
# If there's no query on the left, let's remove the junk left behind |
318 |
$query_str =~ s/^ AND //; |
322 |
$query_str =~ s/^ AND //; |
319 |
my %options; |
323 |
my %options; |
320 |
$options{sort} = \@sort_params; |
324 |
$options{sort} = \@sort_params; |
321 |
$options{is_opac} = $params->{is_opac}; |
325 |
$options{is_opac} = $params->{is_opac}; |
322 |
$options{weighted_fields} = $params->{weighted_fields}; |
326 |
$options{weighted_fields} = $params->{weighted_fields}; |
323 |
$options{whole_record} = $params->{whole_record}; |
327 |
$options{whole_record} = $params->{whole_record}; |
324 |
$options{field_match_boost_query} = $field_match_boost_query if @$field_match_boost_query; |
328 |
$options{field_match_boost_query} = $field_match_boost_query if @$field_match_boost_query; |
325 |
$query = $self->build_query( $query_str, %options ); |
329 |
$query = $self->build_query( $query_str, %options ); |
326 |
} |
330 |
} |
327 |
|
331 |
|
328 |
# We roughly emulate the CGI parameters of the zebra query builder |
332 |
# We roughly emulate the CGI parameters of the zebra query builder |
329 |
my $query_cgi = ''; |
333 |
my $query_cgi = ''; |
330 |
shift @$operators; # Shift out the one we unshifted before |
334 |
shift @$operators; # Shift out the one we unshifted before |
331 |
my $ea = each_array( @$operands, @$operators, @$indexes ); |
335 |
my $ea = each_array( @$operands, @$operators, @$indexes ); |
332 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
336 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
333 |
$query_cgi .= '&' if $query_cgi; |
337 |
$query_cgi .= '&' if $query_cgi; |
334 |
$query_cgi .= 'idx=' . uri_escape_utf8( $index // '') . '&q=' . uri_escape_utf8( $oand ); |
338 |
$query_cgi .= 'idx=' . uri_escape_utf8( $index // '' ) . '&q=' . uri_escape_utf8($oand); |
335 |
$query_cgi .= '&op=' . uri_escape_utf8( $otor ) if $otor; |
339 |
$query_cgi .= '&op=' . uri_escape_utf8($otor) if $otor; |
336 |
} |
340 |
} |
337 |
$query_cgi .= '&scan=1' if ( $scan ); |
341 |
$query_cgi .= '&scan=1' if ($scan); |
338 |
|
342 |
|
339 |
my $simple_query; |
343 |
my $simple_query; |
340 |
$simple_query = $operands->[0] if @$operands == 1; |
344 |
$simple_query = $operands->[0] if @$operands == 1; |
341 |
my $query_desc; |
345 |
my $query_desc; |
342 |
if ( $simple_query ) { |
346 |
if ($simple_query) { |
343 |
$query_desc = $simple_query; |
347 |
$query_desc = $simple_query; |
344 |
} else { |
348 |
} else { |
345 |
$query_desc = $search_param_query_str; |
349 |
$query_desc = $search_param_query_str; |
346 |
} |
350 |
} |
347 |
my $limit = $self->_join_queries( $self->_convert_index_strings(@$limits)); |
351 |
my $limit = $self->_join_queries( $self->_convert_index_strings(@$limits) ); |
348 |
my $limit_cgi = ( $orig_limits and @$orig_limits ) |
352 |
my $limit_cgi = |
349 |
? '&limit=' . join( '&limit=', map { uri_escape_utf8($_) } @$orig_limits ) |
353 |
( $orig_limits and @$orig_limits ) |
350 |
: ''; |
354 |
? '&limit=' . join( '&limit=', map { uri_escape_utf8($_) } @$orig_limits ) |
|
|
355 |
: ''; |
351 |
my $limit_desc; |
356 |
my $limit_desc; |
352 |
$limit_desc = "$limit" if $limit; |
357 |
$limit_desc = "$limit" if $limit; |
353 |
|
358 |
|
354 |
- |
|
|