1 package Koha::SearchEngine::Solr::QueryBuilder;
3 # This file is part of Koha.
5 # Copyright 2012 BibLibre
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
23 with 'Koha::SearchEngine::QueryBuilderRole';
25 sub build_advanced_query {
26 my ($class, $indexes, $operands, $operators) = @_;
32 @$operands or return "*:*"; #push @$operands, "[* TO *]";
35 for my $kw (@$operands){
36 $kw =~ s/(\w*\*)/\L$1\E/g; # Lower case on words with right truncation
37 $kw =~ s/(\s*\w*\?+\w*\s*)/\L$1\E/g; # Lower case on words contain wildcard ?
38 $kw =~ s/([^\\]):/$1\\:/g; # escape colons if not already escaped
41 if ( (my @x = eval {@$indexes} ) == 0 ){
42 # There is no index, then query is in first operand
47 # Catch index name if it's not 'all_fields'
48 if ( @$indexes[$i] ne 'all_fields' ) {
49 $index_name = @$indexes[$i];
54 # Generate index:operand
55 $q .= BuildTokenString($index_name, $kw);
61 $index_name = @$indexes[$i] if @$indexes[$i];
62 my $operator = defined @$operators[$i-1] ? @$operators[$i-1] : 'AND';
63 for ( uc ( $operator ) ) {
65 $q .= BuildTokenString($index_name, $kw, 'OR');
68 $q .= BuildTokenString($index_name, $kw, 'NOT');
71 $q .= BuildTokenString($index_name, $kw, 'AND');
81 sub BuildTokenString {
82 my ($index, $string, $operator) = @_;
85 if ($index ne 'all_fields' && $index ne ''){
86 # Operand can contains an expression in brackets
89 and not ( $string =~ /^\(.*\)$/ )
90 and not $string =~ /\[.*TO.*\]/ ) {
91 my @dqs; #double-quoted string
92 while ( $string =~ /"(?:[^"\\]++|\\.)*+"/g ) {
94 $string =~ s/\ *\Q$&\E\ *//; # Remove useless space before and after
97 my @words = defined $string ? split ' ', $string : undef;
98 my $join = join qq{ AND } , map {
100 if ( $index =~ /^date_/ ) {
101 #$value = C4::Search::Engine::Solr::buildDateOperand( $value ); TODO
103 ( $value =~ /^"/ and $value ne '""'
104 and $index ne "emallfields"
105 and $index =~ /(txt_|ste_)/ )
106 ? qq{em$index:$value}
111 if ( $index =~ /^date_/ ) {
112 #$string = C4::Search::Engine::Solr::buildDateOperand( $string ); TODO
115 $r = "$index:$string";
121 return " $operator $r" if $operator;
126 my ($class, $query) = @_;
128 return "*:*" if not defined $query;
130 # Particular *:* query
131 if ($query eq '*:*'){
135 $query =~ s/(\w*\*)/\L$1\E/g; # Lower case on words with right truncation
136 $query =~ s/(\s*\w*\?+\w*\s*)/\L$1\E/g; # Lower case on words contain wildcard ?
138 my @quotes; # Process colons in quotes
139 while ( $query =~ /'(?:[^'\\]++|\\.)*+'/g ) {
144 my $replacement = $_;
145 $replacement =~ s/[^\\]\K:/\\:/g;
146 $query =~ s/$_/$replacement/;
149 $query =~ s/ : / \\: /g; # escape colons if " : "
151 my $new_query = $query;#C4::Search::Query::splitToken($query); TODO
153 $new_query =~ s/all_fields://g;
155 # Upper case for operators
156 $new_query =~ s/ or / OR /g;
157 $new_query =~ s/ and / AND /g;
158 $new_query =~ s/ not / NOT /g;