Bug Fixing : NZsearch
authorroot <root@henridamienlaurent.dyndns.org>
Fri, 30 Nov 2007 16:14:09 +0000 (10:14 -0600)
committerJoshua Ferraro <jmf@liblime.com>
Sun, 2 Dec 2007 20:57:54 +0000 (14:57 -0600)
parenthesis introduce a priority.
yr:XXXX-YYYY is now processed correctly.

Signed-off-by: Chris Cormack <crc@liblime.com>
Signed-off-by: Joshua Ferraro <jmf@liblime.com>
C4/Search.pm
catalogue/search.pl

index d408dcb..e19e3dc 100644 (file)
@@ -1181,8 +1181,55 @@ sub NZanalyse {
     # split the query string in 3 parts : X AND Y means : $left="X", $operand="AND" and $right="Y"
     # then, call again NZanalyse with $left and $right
     # (recursive until we find a leaf (=> something without and/or/not)
-    $string =~ /(.*)( and | or | not | AND | OR | NOT )(.*)/;
-    my $left = $1;
+    #process parenthesis before.   
+    if ($string =~ /^\s*\((.*)\)(( and | or | not | AND | OR | NOT )(.*))?/){
+      my $left = $1;
+      warn "left :".$left;   
+      my $right = $4;
+      my $operator = lc($3); # FIXME: and/or/not are operators, not operands
+      my $leftresult = NZanalyse($left,$server);
+      if ($operator) {
+        my $rightresult = NZanalyse($right,$server);
+        # OK, we have the results for right and left part of the query
+        # depending of operand, intersect, union or exclude both lists
+        # to get a result list
+        if ($operator eq ' and ') {
+            my @leftresult = split /;/, $leftresult;
+#             my @rightresult = split /;/,$leftresult;
+            my $finalresult;
+            # parse the left results, and if the biblionumber exist in the right result, save it in finalresult
+            # the result is stored twice, to have the same weight for AND than OR.
+            # example : TWO : 61,61,64,121 (two is twice in the biblio #61) / TOWER : 61,64,130
+            # result : 61,61,61,61,64,64 for two AND tower : 61 has more weight than 64
+            foreach (@leftresult) {
+                if ($rightresult =~ "$_;") {
+                    $finalresult .= "$_;$_;";
+                }
+            }
+            return $finalresult;
+        } elsif ($operator eq ' or ') {
+            # just merge the 2 strings
+            return $leftresult.$rightresult;
+        } elsif ($operator eq ' not ') {
+            my @leftresult = split /;/, $leftresult;
+#             my @rightresult = split /;/,$leftresult;
+            my $finalresult;
+            foreach (@leftresult) {
+                unless ($rightresult =~ "$_;") {
+                    $finalresult .= "$_;";
+                }
+            }
+            return $finalresult;
+        } else {
+            # this error is impossible, because of the regexp that isolate the operand, but just in case...
+            return $leftresult;
+            exit;        
+        }
+      }   
+    }  
+    warn "string :".$string;
+    $string =~ /(.*?)( and | or | not | AND | OR | NOT )(.*)/;
+    my $left = $1;   
     my $right = $3;
     my $operand = lc($2); # FIXME: and/or/not are operators, not operands
     # it's not a leaf, we have a and/or/not
@@ -1231,7 +1278,7 @@ sub NZanalyse {
     } else {
         $string =~  s/__X__/"$commacontent"/ if $commacontent;
         $string =~ s/-|\.|\?|,|;|!|'|\(|\)|\[|\]|{|}|"|&|\+|\*|\// /g;
-         warn "leaf : $string\n" if $DEBUG;
+        warn "leaf : $string\n" if $DEBUG;
         # parse the string in in operator/operand/value again
         $string =~ /(.*)(>=|<=)(.*)/;
         my $left = $1;
@@ -1258,8 +1305,10 @@ sub NZanalyse {
             my $sth = $dbh->prepare("SELECT biblionumbers,value FROM nozebra WHERE server=? AND indexname=? AND value $operator ?");
             warn "$left / $operator / $right\n";
             # split each word, query the DB and build the biblionumbers result
+            #sanitizing leftpart      
+            $left=~s/^\s+|\s+$//;
+            my ($biblionumbers,$value);
             foreach (split / /,$right) {
-                my ($biblionumbers,$value);
                 next unless $_;
                 warn "EXECUTE : $server, $left, $_";
                 $sth->execute($server, $left, $_) or warn "execute failed: $!";
@@ -1267,7 +1316,7 @@ sub NZanalyse {
                     # if we are dealing with a numeric value, use only numeric results (in case of >=, <=, > or <)
                     # otherwise, fill the result
                     $biblionumbers .= $line unless ($right =~ /\d/ && $value =~ /\D/);
-                    warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
+                    warn "result : $value ". ($right =~ /\d/) . "==".(!$value =~ /\d/) ;#= $line";
                 }
                 # do a AND with existing list if there is one, otherwise, use the biblionumbers list as 1st result list
                 if ($results) {
@@ -1326,7 +1375,7 @@ sub NZanalyse {
                 }
             }
         }
-         warn "return : $results for LEAF : $string" if $DEBUG;
+#         warn "return : $results for LEAF : $string" if $DEBUG;
         return $results;
     }
 }
index 0b6fba6..40be2cd 100755 (executable)
@@ -438,6 +438,9 @@ my @results_array;
 my $results_hashref;
 
 if (C4::Context->preference('NoZebra')) {
+    $query=~s/yr(:|=)\s*([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
+    $simple_query=~s/yr\s*(:|=)([\d]{1,4})-([\d]{1,4})/(yr>=$2 and yr<=$3)/g;
+    warn $query; 
     eval {
         ($error, $results_hashref, $facets) = NZgetRecords($query,$simple_query,\@sort_by,\@servers,$results_per_page,$offset,$expanded_facet,$branches,$query_type,$scan);
     };