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 |
} |