|
Lines 209-219
sub build_query_compat {
Link Here
|
| 209 |
# each search thing is a handy unit. |
209 |
# each search thing is a handy unit. |
| 210 |
unshift @$operators, undef; # The first one can't have an op |
210 |
unshift @$operators, undef; # The first one can't have an op |
| 211 |
my @search_params; |
211 |
my @search_params; |
|
|
212 |
my $truncate = C4::Context->preference("QueryAutoTruncate") || 0; |
| 212 |
my $ea = each_array( @$operands, @$operators, @index_params ); |
213 |
my $ea = each_array( @$operands, @$operators, @index_params ); |
| 213 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
214 |
while ( my ( $oand, $otor, $index ) = $ea->() ) { |
| 214 |
next if ( !defined($oand) || $oand eq '' ); |
215 |
next if ( !defined($oand) || $oand eq '' ); |
|
|
216 |
$oand = $self->_clean_search_term($oand); |
| 217 |
$oand = $self->_truncate_terms($oand) if ($truncate); |
| 215 |
push @search_params, { |
218 |
push @search_params, { |
| 216 |
operand => $self->_clean_search_term($oand), # the search terms |
219 |
operand => $oand, # the search terms |
| 217 |
operator => defined($otor) ? uc $otor : undef, # AND and so on |
220 |
operator => defined($otor) ? uc $otor : undef, # AND and so on |
| 218 |
$index ? %$index : (), |
221 |
$index ? %$index : (), |
| 219 |
}; |
222 |
}; |
|
Lines 314-324
sub build_authorities_query {
Link Here
|
| 314 |
} |
317 |
} |
| 315 |
else { |
318 |
else { |
| 316 |
# regular wordlist stuff |
319 |
# regular wordlist stuff |
| 317 |
# push @query_parts, { match => {$wh => { query => $val, operator => 'and' }} }; |
320 |
my @tokens = $self->_split_query( $val ); |
| 318 |
my @values = split(' ',$val); |
321 |
foreach my $token ( @tokens ) { |
| 319 |
foreach my $v (@values) { |
322 |
$token = $self->_truncate_terms( |
| 320 |
push @query_parts, { wildcard => { "$wh.phrase" => "*" . lc $v . "*" } }; |
323 |
$self->_clean_search_term( $token ) |
|
|
324 |
); |
| 321 |
} |
325 |
} |
|
|
326 |
my $query = $self->_join_queries( @tokens ); |
| 327 |
push @query_parts, { query_string => { default_field => $wh, query => $query } }; |
| 322 |
} |
328 |
} |
| 323 |
} |
329 |
} |
| 324 |
|
330 |
|
|
Lines 714-727
to ensure those parts are correct.
Link Here
|
| 714 |
sub _clean_search_term { |
720 |
sub _clean_search_term { |
| 715 |
my ( $self, $term ) = @_; |
721 |
my ( $self, $term ) = @_; |
| 716 |
|
722 |
|
| 717 |
my $auto_truncation = C4::Context->preference("QueryAutoTruncate") || 0; |
|
|
| 718 |
|
| 719 |
# Some hardcoded searches (like with authorities) produce things like |
723 |
# Some hardcoded searches (like with authorities) produce things like |
| 720 |
# 'an=123', when it ought to be 'an:123' for our purposes. |
724 |
# 'an=123', when it ought to be 'an:123' for our purposes. |
| 721 |
$term =~ s/=/:/g; |
725 |
$term =~ s/=/:/g; |
| 722 |
$term = $self->_convert_index_strings_freeform($term); |
726 |
$term = $self->_convert_index_strings_freeform($term); |
| 723 |
$term =~ s/[{}]/"/g; |
727 |
$term =~ s/[{}]/"/g; |
| 724 |
$term = $self->_truncate_terms($term) if ($auto_truncation); |
|
|
| 725 |
return $term; |
728 |
return $term; |
| 726 |
} |
729 |
} |
| 727 |
|
730 |
|
|
Lines 805-825
operands and double quoted strings.
Link Here
|
| 805 |
sub _truncate_terms { |
808 |
sub _truncate_terms { |
| 806 |
my ( $self, $query ) = @_; |
809 |
my ( $self, $query ) = @_; |
| 807 |
|
810 |
|
| 808 |
# '"donald duck" title:"the mouse" and peter" get split into |
811 |
my @tokens = $self->_split_query( $query ); |
| 809 |
# ['', '"donald duck"', '', ' ', '', 'title:"the mouse"', '', ' ', 'and', ' ', 'pete'] |
|
|
| 810 |
my @tokens = split /((?:[\w\-.]+:)?"[^"]+"|\s+)/, $query; |
| 811 |
|
812 |
|
| 812 |
# Filter out empty tokens |
813 |
# Filter out empty tokens |
| 813 |
my @words = grep { $_ !~ /^\s*$/ } @tokens; |
814 |
my @words = grep { $_ !~ /^\s*$/ } @tokens; |
| 814 |
|
815 |
|
| 815 |
# Append '*' to words if needed, ie. if it's not surrounded by quotes, not |
816 |
# Append '*' to words if needed, ie. if it ends in a word character and is not a keyword |
| 816 |
# terminated by '*' and not a keyword |
|
|
| 817 |
my @terms = map { |
817 |
my @terms = map { |
| 818 |
my $w = $_; |
818 |
my $w = $_; |
| 819 |
(/"$/ or /\*$/ or grep {lc($w) eq $_} qw/and or not/) ? $_ : "$_*"; |
819 |
(/\W$/ or grep {lc($w) eq $_} qw/and or not/) ? $_ : "$_*"; |
| 820 |
} @words; |
820 |
} @words; |
| 821 |
|
821 |
|
| 822 |
return join ' ', @terms; |
822 |
return join ' ', @terms; |
| 823 |
} |
823 |
} |
| 824 |
|
824 |
|
|
|
825 |
=head2 _split_query |
| 826 |
|
| 827 |
my @token = $self->_split_query($query_str); |
| 828 |
|
| 829 |
Given a string query this function splits it to tokens taking into account |
| 830 |
any field prefixes and quoted strings. |
| 831 |
|
| 832 |
=cut |
| 833 |
|
| 834 |
sub _split_query { |
| 835 |
my ( $self, $query ) = @_; |
| 836 |
|
| 837 |
# '"donald duck" title:"the mouse" and peter" get split into |
| 838 |
# ['', '"donald duck"', '', ' ', '', 'title:"the mouse"', '', ' ', 'and', ' ', 'pete'] |
| 839 |
my @tokens = split /((?:[\w\-.]+:)?"[^"]+"|\s+)/, $query; |
| 840 |
|
| 841 |
# Filter out empty values |
| 842 |
@tokens = grep( /\S/, @tokens ); |
| 843 |
|
| 844 |
return @tokens; |
| 845 |
} |
| 846 |
|
| 825 |
1; |
847 |
1; |