|
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 1178-1187
sub _search_fields {
Link Here
|
| 1178 |
# Copy values to avoid mutating cached |
1210 |
# Copy values to avoid mutating cached |
| 1179 |
# data (since unsafe is used) |
1211 |
# data (since unsafe is used) |
| 1180 |
my ($field, $weight) = @{$_}; |
1212 |
my ($field, $weight) = @{$_}; |
| 1181 |
["${field}.${subfield}", $weight]; |
1213 |
["${field}.${subfield}", $weight ? $weight : ()]; |
| 1182 |
} @{$search_fields} |
1214 |
} @{$search_fields} |
| 1183 |
]; |
1215 |
]; |
|
|
1216 |
} else { |
| 1217 |
$search_fields = [ |
| 1218 |
map { |
| 1219 |
my ($field, $weight) = @{$_}; |
| 1220 |
$_, ["$field.lang_*", $weight // ()]; |
| 1221 |
} @$search_fields |
| 1222 |
]; |
| 1184 |
} |
1223 |
} |
|
|
1224 |
|
| 1185 |
if ($params->{weighted_fields}) { |
1225 |
if ($params->{weighted_fields}) { |
| 1186 |
return [map { join('^', @{$_}) } @{$search_fields}]; |
1226 |
return [map { join('^', @{$_}) } @{$search_fields}]; |
| 1187 |
} |
1227 |
} |