Bugzilla – Attachment 16183 Details for
Bug 9239
Koha should share Evergreen's QueryParser module for parsing queries
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 9239: Allow the use of QueryParser for all queries
Bug-9239-Allow-the-use-of-QueryParser-for-all-quer.patch (text/plain), 29.21 KB, created by
Jared Camins-Esakov
on 2013-03-17 01:27:15 UTC
(
hide
)
Description:
Bug 9239: Allow the use of QueryParser for all queries
Filename:
MIME Type:
Creator:
Jared Camins-Esakov
Created:
2013-03-17 01:27:15 UTC
Size:
29.21 KB
patch
obsolete
>From 084e1003fe16a0aea69d99e157bbb0cbca06e5a8 Mon Sep 17 00:00:00 2001 >From: Jared Camins-Esakov <jcamins@cpbibliography.com> >Date: Tue, 11 Dec 2012 12:52:40 -0500 >Subject: [PATCH] Bug 9239: Allow the use of QueryParser for all queries > >With the inclusion of this patch, all searches will (try) to use >QueryParser for handling queries for both the bibliographic and authority >databases if UseQueryParser is enabled. If QueryParser is unavailable, >UseQueryParser is disabled, or the search uses CCL indexes, the old >search code will be used. > >To test: >1) Apply patch. >2) Run the unit test with `prove t/QueryParser.t` >3) Enable the UseQueryParser syspref. >4) Try searches that should return results in the following places: > * OPAC (simple search) > * OPAC (advanced search) > * OPAC (authorities) > * Staff client (header search) > * Staff client (advanced search) > * Staff client (cataloging search) > * Staff client (authorities) > * Staff client (importing a batch using a match point) > * Staff client (searching for an item for adding to a label) > * Staff client (acquisitions) > * Staff client (searching for a record to create a serial) > * ANYWHERE ELSE I HAVE FORGOTTEN >5) Disable the UseQueryParser syspref. Repeat at least some of the > searches you did above. >6) If all searches worked, sign off. > >Signed-off-by: Chris Cormack <chris@bigballofwax.co.nz> >Signed-off-by: Elliott Davis <elliott@bywatersolions.com> >Searching still works as expected for variuos places. >QueryParser syspref seemed to be enabled by default > >Signed-off-by: Katrin Fischer <Katrin.Fischer.83@web.de> >Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com> >--- > C4/AuthoritiesMarc.pm | 40 ++++++- > C4/Matcher.pm | 55 +++++----- > C4/Search.pm | 113 +++++++++++++------- > Koha/SuggestionEngine/Plugin/AuthorityFile.pm | 2 +- > cataloguing/addbooks.pl | 10 +- > .../value_builder/marc21_linking_section.pl | 10 +- > cataloguing/value_builder/unimarc_field_4XX.pl | 10 +- > labels/label-item-search.pl | 25 +++-- > misc/migration_tools/bulkmarcimport.pl | 22 +++- > serials/subscription-bib-search.pl | 18 +++- > t/db_dependent/Search.t | 21 ++-- > 11 files changed, 236 insertions(+), 90 deletions(-) > >diff --git a/C4/AuthoritiesMarc.pm b/C4/AuthoritiesMarc.pm >index b6e3690..e30c571 100644 >--- a/C4/AuthoritiesMarc.pm >+++ b/C4/AuthoritiesMarc.pm >@@ -201,6 +201,9 @@ sub SearchAuthorities { > } > } else { > my $query; >+ my $qpquery = ''; >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); > my $attr = ''; > # the marclist may contain "mainentry". In this case, search the tag_to_report, that depends on > # the authtypecode. Then, search on $a of this tag_to_report >@@ -219,6 +222,9 @@ sub SearchAuthorities { > if ($n>1){ > while ($n>1){$query= "\@or ".$query;$n--;} > } >+ if ($QParser) { >+ $qpquery .= '(authtype:' . join('|| authtype:', @auths) . ')'; >+ } > } > > my $dosearch; >@@ -276,6 +282,9 @@ sub SearchAuthorities { > $q2 .=$attr; > $dosearch=1; > ++$attr_cnt; >+ if ($QParser) { >+ $qpquery .= " $tags->[$i]:$value->[$i]"; >+ } > }#if value > } > ##Add how many queries generated >@@ -296,8 +305,21 @@ sub SearchAuthorities { > } elsif ($sortby eq 'AuthidDsc') { > $orderstring = '@attr 7=2 @attr 4=109 @attr 1=Local-Number 0'; > } >- $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''"); >- $query="\@or $orderstring $query" if $orderstring; >+ if ($QParser) { >+ $qpquery .= ' all:all' unless $value->[0]; >+ >+ if ( $value->[0] =~ m/^qp=(.*)$/ ) { >+ $qpquery = $1; >+ } >+ >+ $qpquery .= " #$sortby"; >+ >+ $QParser->parse( $qpquery ); >+ $query = $QParser->target_syntax('authorityserver'); >+ } else { >+ $query=($query?$query:"\@attr 1=_ALLRECORDS \@attr 2=103 ''"); >+ $query="\@or $orderstring $query" if $orderstring; >+ } > > $offset=0 unless $offset; > my $counter = $offset; >@@ -406,7 +428,7 @@ sub CountUsage { > } else { > ### ZOOM search here > my $query; >- $query= "an=".$authid; >+ $query= "an:".$authid; > my ($err,$res,$result) = C4::Search::SimpleSearch($query,0,10); > if ($err) { > warn "Error: $err from search $query"; >@@ -911,11 +933,19 @@ sub FindDuplicateAuthority { > $sth->finish; > # warn "record :".$record->as_formatted." auth_tag_to_report :$auth_tag_to_report"; > # build a request for SearchAuthorities >- my $query='at='.$authtypecode.' '; >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ my $query='at:'.$authtypecode.' '; > my $filtervalues=qr([\001-\040\!\'\"\`\#\$\%\&\*\+,\-\./:;<=>\?\@\(\)\{\[\]\}_\|\~]); > if ($record->field($auth_tag_to_report)) { > foreach ($record->field($auth_tag_to_report)->subfields()) { >- $_->[1]=~s/$filtervalues/ /g; $query.= " and he,wrdl=\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/); >+ $_->[1]=~s/$filtervalues/ /g; $query.= " $op he:\"".$_->[1]."\"" if ($_->[0]=~/[A-z]/); > } > } > my ($error, $results, $total_hits) = C4::Search::SimpleSearch( $query, 0, 1, [ "authorityserver" ] ); >diff --git a/C4/Matcher.pm b/C4/Matcher.pm >index c0634ec..6a7c4f2 100644 >--- a/C4/Matcher.pm >+++ b/C4/Matcher.pm >@@ -626,6 +626,8 @@ sub get_matches { > > my %matches = (); > >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); > foreach my $matchpoint (@{ $self->{'matchpoints'} }) { > my @source_keys = _get_match_keys($source_record, $matchpoint); > next if scalar(@source_keys) == 0; >@@ -634,31 +636,36 @@ sub get_matches { > my $error; > my $searchresults; > my $total_hits; >- if ($self->{'record_type'} eq 'biblio') { >- $query = join(" or ", map { "$matchpoint->{'index'}=$_" } @source_keys); >-# FIXME only searching biblio index at the moment >+ if ($QParser) { >+ $query = join(" || ", map { "$matchpoint->{'index'}:$_" } @source_keys); > require C4::Search; >- ($error, $searchresults, $total_hits) = C4::Search::SimpleSearch($query, 0, $max_matches); >- } elsif ($self->{'record_type'} eq 'authority') { >- my $authresults; >- my @marclist; >- my @and_or; >- my @excluding = []; >- my @operator; >- my @value; >- foreach my $key (@source_keys) { >- push @marclist, $matchpoint->{'index'}; >- push @and_or, 'or'; >- push @operator, 'exact'; >- push @value, $key; >- } >- require C4::AuthoritiesMarc; >- ($authresults, $total_hits) = C4::AuthoritiesMarc::SearchAuthorities( >- \@marclist, \@and_or, \@excluding, \@operator, >- \@value, 0, 20, undef, 'AuthidAsc', 1 >- ); >- foreach my $result (@$authresults) { >- push @$searchresults, $result->{'authid'}; >+ ($error, $searchresults, $total_hits) = C4::Search::SimpleSearch($query, 0, $max_matches, [ $self->{'record_type'} . 'server' ] ); >+ } else { >+ if ($self->{'record_type'} eq 'biblio') { >+ $query = join(" or ", map { "$matchpoint->{'index'}=$_" } @source_keys); >+ require C4::Search; >+ ($error, $searchresults, $total_hits) = C4::Search::SimpleSearch($query, 0, $max_matches); >+ } elsif ($self->{'record_type'} eq 'authority') { >+ my $authresults; >+ my @marclist; >+ my @and_or; >+ my @excluding = []; >+ my @operator; >+ my @value; >+ foreach my $key (@source_keys) { >+ push @marclist, $matchpoint->{'index'}; >+ push @and_or, 'or'; >+ push @operator, 'exact'; >+ push @value, $key; >+ } >+ require C4::AuthoritiesMarc; >+ ($authresults, $total_hits) = C4::AuthoritiesMarc::SearchAuthorities( >+ \@marclist, \@and_or, \@excluding, \@operator, >+ \@value, 0, 20, undef, 'AuthidAsc', 1 >+ ); >+ foreach my $result (@$authresults) { >+ push @$searchresults, $result->{'authid'}; >+ } > } > } > >diff --git a/C4/Search.pm b/C4/Search.pm >index ce6129d..4039a68 100644 >--- a/C4/Search.pm >+++ b/C4/Search.pm >@@ -100,9 +100,25 @@ sub FindDuplicate { > if ( $result->{isbn} ) { > $result->{isbn} =~ s/\(.*$//; > $result->{isbn} =~ s/\s+$//; >- $query = "isbn=$result->{isbn}"; >+ $query = "isbn:$result->{isbn}"; > } > else { >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $titleindex; >+ my $authorindex; >+ my $op; >+ >+ if ($QParser) { >+ $titleindex = 'title|exact'; >+ $authorindex = 'author|exact'; >+ $op = '&&'; >+ } else { >+ $titleindex = 'ti,ext'; >+ $authorindex = 'au,ext'; >+ $op = 'and'; >+ } >+ > $result->{title} =~ s /\\//g; > $result->{title} =~ s /\"//g; > $result->{title} =~ s /\(//g; >@@ -111,7 +127,7 @@ sub FindDuplicate { > # FIXME: instead of removing operators, could just do > # quotes around the value > $result->{title} =~ s/(and|or|not)//g; >- $query = "ti,ext=$result->{title}"; >+ $query = "$titleindex:\"$result->{title}\""; > if ( $result->{author} ) { > $result->{author} =~ s /\\//g; > $result->{author} =~ s /\"//g; >@@ -120,7 +136,7 @@ sub FindDuplicate { > > # remove valid operators > $result->{author} =~ s/(and|or|not)//g; >- $query .= " and au,ext=$result->{author}"; >+ $query .= " $op $authorindex:\"$result->{author}\""; > } > } > >@@ -224,11 +240,21 @@ sub SimpleSearch { > my $results = []; > my $total_hits = 0; > >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') && ! ($query =~ m/\w,\w|\w=\w/)); >+ > # Initialize & Search Zebra > for ( my $i = 0 ; $i < @servers ; $i++ ) { > eval { > $zconns[$i] = C4::Context->Zconn( $servers[$i], 1 ); >- $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]); >+ if ($QParser) { >+ $query =~ s/=/:/g; >+ $QParser->parse( $query ); >+ $query = $QParser->target_syntax($servers[$i]); >+ $zoom_queries[$i] = new ZOOM::Query::PQF( $query, $zconns[$i]); >+ } else { >+ $zoom_queries[$i] = new ZOOM::Query::CCL2RPN( $query, $zconns[$i]); >+ } > $tmpresults[$i] = $zconns[$i]->search( $zoom_queries[$i] ); > > # error handling >@@ -1091,7 +1117,9 @@ on authority data). > =cut > > sub _handle_exploding_index { >- my ( $index, $term ) = @_; >+ my ($QParser, $struct, $filter, $params, $negate, $server) = @_; >+ my $index = $filter; >+ my $term = join(' ', @$params); > > return unless ($index =~ m/(su-br|su-na|su-rl)/ && $term); > >@@ -1099,8 +1127,8 @@ sub _handle_exploding_index { > > my $codesubfield = $marcflavour eq 'UNIMARC' ? '5' : 'w'; > my $wantedcodes = ''; >- my @subqueries = ( "(su=\"$term\")"); >- my ($error, $results, $total_hits) = SimpleSearch( "Heading,wrdl=$term", undef, undef, [ "authorityserver" ] ); >+ my @subqueries = ( "su:\"$term\""); >+ my ($error, $results, $total_hits) = SimpleSearch( "he:$term", undef, undef, [ "authorityserver" ] ); > foreach my $auth (@$results) { > my $record = MARC::Record->new_from_usmarc($auth); > my @references = $record->field('5..'); >@@ -1114,11 +1142,13 @@ sub _handle_exploding_index { > } > foreach my $reference (@references) { > my $codes = $reference->subfield($codesubfield); >- push @subqueries, '(su="' . $reference->as_string('abcdefghijlmnopqrstuvxyz') . '")' if (($codes && $codes eq $wantedcodes) || !$wantedcodes); >+ push @subqueries, 'su:"' . $reference->as_string('abcdefghijlmnopqrstuvxyz') . '"' if (($codes && $codes eq $wantedcodes) || !$wantedcodes); > } > } > } >- return join(' or ', @subqueries); >+ my $query = '(' x scalar(@subqueries) . join(') || ', @subqueries) . ')'; >+ warn $query; >+ return $query; > } > > =head2 parseQuery >@@ -1145,37 +1175,42 @@ sub parseQuery { > my $query = $operands[0]; > my $index; > my $term; >+ my $query_desc; > >-# TODO: once we are using QueryParser, all this special case code for >-# exploded search indexes will be replaced by a callback to >-# _handle_exploding_index >- if ( $query =~ m/^(.*)\b(su-br|su-na|su-rl)[:=](\w.*)$/ ) { >- $query = $1; >- $index = $2; >- $term = $3; >- } else { >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser') || $query =~ s/^qp=//); >+ undef $QParser if ($query =~ m/^(ccl=|pqf=|cql=)/ || grep (/\w,\w|\w=\w/, @operands) ); >+ >+ if ($QParser) >+ { > $query = ''; >- for ( my $i = 0 ; $i <= @operands ; $i++ ) { >- if ($operands[$i] && $indexes[$i] =~ m/(su-br|su-na|su-rl)/) { >- $index = $indexes[$i]; >- $term = $operands[$i]; >- } elsif ($operands[$i]) { >- $query .= $operators[$i] eq 'or' ? ' or ' : ' and ' if ($query); >- $query .= "($indexes[$i]:$operands[$i])"; >- } >+ for ( my $ii = 0 ; $ii <= @operands ; $ii++ ) { >+ next unless $operands[$ii]; >+ $query .= $operators[ $ii - 1 ] eq 'or' ? ' || ' : ' && ' >+ if ($query); >+ $query .= >+ ( $operators[$ii] ? "$operators[$ii]:" : '' ) . $operands[$ii]; >+ } >+ foreach my $limit (@limits) { >+ } >+ foreach my $modifier (@sort_by) { >+ $query .= " #$modifier"; > } >- } > >- if ($index) { >- my $queryPart = _handle_exploding_index($index, $term); >- if ($queryPart) { >- $query .= "($queryPart)"; >+ $query_desc = $query; >+ if ( C4::Context->preference("QueryWeightFields") ) { > } >- $operators = (); >- $operands[0] = "ccl=$query"; >+ $QParser->add_bib1_filter_map( 'biblioserver', 'su-br', { 'callback' => \&_handle_exploding_index }); >+ $QParser->add_bib1_filter_map( 'biblioserver', 'su-na', { 'callback' => \&_handle_exploding_index }); >+ $QParser->add_bib1_filter_map( 'biblioserver', 'su-rl', { 'callback' => \&_handle_exploding_index }); >+ $QParser->parse( $query ); >+ $operands[0] = "pqf=" . $QParser->target_syntax('biblioserver'); >+# TODO: once we are using QueryParser, all this special case code for >+# exploded search indexes will be replaced by a callback to >+# _handle_exploding_index > } > >- return ( $operators, \@operands, $indexes, $limits, $sort_by, $scan, $lang); >+ return ( $operators, \@operands, $indexes, $limits, $sort_by, $scan, $lang, $query_desc); > } > > =head2 buildQuery >@@ -1199,7 +1234,8 @@ sub buildQuery { > > warn "---------\nEnter buildQuery\n---------" if $DEBUG; > >- ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang) = parseQuery($operators, $operands, $indexes, $limits, $sort_by, $scan, $lang); >+ my $query_desc; >+ ( $operators, $operands, $indexes, $limits, $sort_by, $scan, $lang, $query_desc) = parseQuery($operators, $operands, $indexes, $limits, $sort_by, $scan, $lang); > > # dereference > my @operators = $operators ? @$operators : (); >@@ -1227,7 +1263,6 @@ sub buildQuery { > > # initialize the variables we're passing back > my $query_cgi; >- my $query_desc; > my $query_type; > > my $limit; >@@ -1262,7 +1297,13 @@ sub buildQuery { > return ( undef, $', $', "q=cql=$'", $', '', '', '', '', 'cql' ); > } > if ( $query =~ /^pqf=/ ) { >- return ( undef, $', $', "q=pqf=$'", $', '', '', '', '', 'pqf' ); >+ if ($query_desc) { >+ $query_cgi = "q=$query_desc"; >+ } else { >+ $query_desc = $'; >+ $query_cgi = "q=pqf=$'"; >+ } >+ return ( undef, $', $', $query_cgi, $query_desc, '', '', '', '', 'pqf' ); > } > > # pass nested queries directly >diff --git a/Koha/SuggestionEngine/Plugin/AuthorityFile.pm b/Koha/SuggestionEngine/Plugin/AuthorityFile.pm >index fdc41c5..7df5fa2 100644 >--- a/Koha/SuggestionEngine/Plugin/AuthorityFile.pm >+++ b/Koha/SuggestionEngine/Plugin/AuthorityFile.pm >@@ -85,7 +85,7 @@ sub get_suggestions { > # FIXME: calling into C4 > require C4::AuthoritiesMarc; > my ( $searchresults, $count ) = C4::AuthoritiesMarc::SearchAuthorities( >- \@marclist, \@and_or, \@excluding, \@operator, >+ @marclist, @and_or, @excluding, @operator, > @value, 0, $param->{'count'}, '', > 'Relevance', 0 > ); >diff --git a/cataloguing/addbooks.pl b/cataloguing/addbooks.pl >index c8a8071..f643599 100755 >--- a/cataloguing/addbooks.pl >+++ b/cataloguing/addbooks.pl >@@ -70,10 +70,16 @@ if ($query) { > > # build query > my @operands = $query; >- my ( $builterror,$builtquery,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type) = buildQuery(undef,\@operands); >+ >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ unless ($QParser) { >+ my ( $builterror,$builtquery,$simple_query,$query_cgi,$query_desc,$limit,$limit_cgi,$limit_desc,$stopwords_removed,$query_type) = buildQuery(undef,\@operands); >+ $query = $builtquery; >+ } > > # find results >- my ( $error, $marcresults, $total_hits ) = SimpleSearch($builtquery, $results_per_page * ($page - 1), $results_per_page); >+ my ( $error, $marcresults, $total_hits ) = SimpleSearch($query, $results_per_page * ($page - 1), $results_per_page); > > if ( defined $error ) { > $template->param( error => $error ); >diff --git a/cataloguing/value_builder/marc21_linking_section.pl b/cataloguing/value_builder/marc21_linking_section.pl >index f317f8b..f30086e 100644 >--- a/cataloguing/value_builder/marc21_linking_section.pl >+++ b/cataloguing/value_builder/marc21_linking_section.pl >@@ -190,7 +190,15 @@ sub plugin { > my $startfrom = $query->param('startfrom'); > my $resultsperpage = $query->param('resultsperpage') || 20; > my $orderby; >- $search = 'kw,wrdl=' . $search . ' and mc-itemtype=' . $itype if $itype; >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ $search = 'kw:' . $search . " $op mc-itemtype:" . $itype if $itype; > my ( $errors, $results, $total_hits ) = > SimpleSearch( $search, $startfrom * $resultsperpage, > $resultsperpage ); >diff --git a/cataloguing/value_builder/unimarc_field_4XX.pl b/cataloguing/value_builder/unimarc_field_4XX.pl >index acc0854..0202438 100755 >--- a/cataloguing/value_builder/unimarc_field_4XX.pl >+++ b/cataloguing/value_builder/unimarc_field_4XX.pl >@@ -341,7 +341,15 @@ sub plugin { > my $startfrom = $query->param('startfrom'); > my $resultsperpage = $query->param('resultsperpage') || 20; > my $orderby; >- $search = 'kw,wrdl='.$search.' and mc-itemtype='.$itype if $itype; >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ $search = 'kw:'.$search." $op mc-itemtype:".$itype if $itype; > my ( $errors, $results, $total_hits ) = SimpleSearch($search, $startfrom * $resultsperpage, $resultsperpage ); > if (defined $errors ) { > $results = []; >diff --git a/labels/label-item-search.pl b/labels/label-item-search.pl >index ef7d9bf..eeb46f8 100755 >--- a/labels/label-item-search.pl >+++ b/labels/label-item-search.pl >@@ -66,10 +66,12 @@ my $display_columns = [ {_add => {label => "Add Item", link_fi > ]; > > if ( $op eq "do_search" ) { >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); > $idx = $query->param('idx'); > $ccl_textbox = $query->param('ccl_textbox'); > if ( $ccl_textbox && $idx ) { >- $ccl_query = "$idx=$ccl_textbox"; >+ $ccl_query = "$idx:$ccl_textbox"; > } > > $datefrom = $query->param('datefrom'); >@@ -77,15 +79,26 @@ if ( $op eq "do_search" ) { > > if ($datefrom) { > $datefrom = C4::Dates->new($datefrom); >- $ccl_query .= ' and ' if $ccl_textbox; >- $ccl_query .= >- "acqdate,st-date-normalized,ge=" . $datefrom->output("iso"); >+ if ($QParser) { >+ $ccl_query .= ' && ' if $ccl_textbox; >+ $ccl_query .= >+ "acqdate(" . $datefrom->output("iso") . '-)'; >+ } else { >+ $ccl_query .= ' and ' if $ccl_textbox; >+ $ccl_query .= >+ "acqdate,st-date-normalized,ge=" . $datefrom->output("iso"); >+ } > } > > if ($dateto) { > $dateto = C4::Dates->new($dateto); >- $ccl_query .= ' and ' if ( $ccl_textbox || $datefrom ); >- $ccl_query .= "acqdate,st-date-normalized,le=" . $dateto->output("iso"); >+ if ($QParser) { >+ $ccl_query .= ' && ' if ( $ccl_textbox || $datefrom ); >+ $ccl_query .= "acqdate(-" . $dateto->output("iso") . ')'; >+ } else { >+ $ccl_query .= ' and ' if ( $ccl_textbox || $datefrom ); >+ $ccl_query .= "acqdate,st-date-normalized,le=" . $datefrom->output("iso"); >+ } > } > > my $offset = $startfrom > 1 ? $startfrom - 1 : 0; >diff --git a/misc/migration_tools/bulkmarcimport.pl b/misc/migration_tools/bulkmarcimport.pl >index e0f905c..682af89 100755 >--- a/misc/migration_tools/bulkmarcimport.pl >+++ b/misc/migration_tools/bulkmarcimport.pl >@@ -432,7 +432,15 @@ sub build_query { > my $string = build_simplequery($matchingpoint,$record); > push @searchstrings,$string if (length($string)>0); > } >- return join(" and ",@searchstrings); >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ return join(" $op ",@searchstrings); > } > sub build_simplequery { > my $element=shift; >@@ -442,10 +450,18 @@ sub build_simplequery { > my @searchstrings; > foreach my $field ($record->field($tag)){ > if (length($field->as_string("$subfields"))>0){ >- push @searchstrings,"$index,wrdl=\"".$field->as_string("$subfields")."\""; >+ push @searchstrings,"$index:\"".$field->as_string("$subfields")."\""; > } > } >- return join(" and ",@searchstrings); >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ return join(" $op ",@searchstrings); > } > sub report_item_errors { > my $biblionumber = shift; >diff --git a/serials/subscription-bib-search.pl b/serials/subscription-bib-search.pl >index 623efe2..95e4aa7 100755 >--- a/serials/subscription-bib-search.pl >+++ b/serials/subscription-bib-search.pl >@@ -90,11 +90,19 @@ if ($op eq "do_search" && $query) { > # add the itemtype limit if applicable > my $itemtypelimit = $input->param('itemtypelimit'); > if ( $itemtypelimit ) { >- if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') { >- $query .= " AND $itype_or_itemtype=$itemtypelimit"; >- } else { >- $query .= " AND $advanced_search_types=$itemtypelimit"; >- } >+ my $QParser; >+ $QParser = C4::Context->queryparser if (C4::Context->preference('UseQueryParser')); >+ my $op; >+ if ($QParser) { >+ $op = '&&'; >+ } else { >+ $op = 'and'; >+ } >+ if (!$advanced_search_types or $advanced_search_types eq 'itemtypes') { >+ $query .= " $op $itype_or_itemtype:$itemtypelimit"; >+ } else { >+ $query .= " $op $advanced_search_types:$itemtypelimit"; >+ } > } > $debug && warn $query; > $resultsperpage= $input->param('resultsperpage'); >diff --git a/t/db_dependent/Search.t b/t/db_dependent/Search.t >index 6d3d7a3..28bee10 100644 >--- a/t/db_dependent/Search.t >+++ b/t/db_dependent/Search.t >@@ -32,6 +32,7 @@ my $QueryAutoTruncate = 0; > my $QueryWeightFields = 0; > my $QueryFuzzy = 0; > my $QueryRemoveStopwords = 0; >+my $UseQueryParser = 0; > my $contextmodule = new Test::MockModule('C4::Context'); > $contextmodule->mock('_new_dbh', sub { > my $dbh = DBI->connect( 'DBI:Mock:', '', '' ) >@@ -53,6 +54,8 @@ $contextmodule->mock('preference', sub { > return $QueryFuzzy; > } elsif ($pref eq 'QueryRemoveStopwords') { > return $QueryRemoveStopwords; >+ } elsif ($pref eq 'UseQueryParser') { >+ return $UseQueryParser; > } elsif ($pref eq 'maxRecordsForFacets') { > return 20; > } elsif ($pref eq 'FacetLabelTruncationLength') { >@@ -109,6 +112,11 @@ $contextmodule->mock('marcfromkohafield', sub { > ); > return \%hash; > }); >+$contextmodule->mock('queryparser', sub { >+ my $QParser = Koha::QueryParser::Driver::PQF->new(); >+ $QParser->load_config("$datadir/etc/searchengine/queryparser.yaml"); >+ return $QParser; >+}); > my $context = new C4::Context("$datadir/etc/koha-conf.xml"); > $context->set_context(); > >@@ -521,7 +529,7 @@ my $searchmodule = new Test::MockModule('C4::Search'); > $searchmodule->mock('SimpleSearch', sub { > my $query = shift; > >- is($query, "Heading,wrdl=$term", "Searching for expected term '$term' for exploding") or return '', [], 0; >+ is($query, "he:$term", "Searching for expected term '$term' for exploding") or return '', [], 0; > > my $record = MARC::Record->new; > if ($query =~ m/Arizona/) { >@@ -538,6 +546,7 @@ $searchmodule->mock('SimpleSearch', sub { > return '', [ $record->as_usmarc() ], 1; > }); > >+$UseQueryParser = 1; > $term = 'Arizona'; > ( $error, $query, $simple_query, $query_cgi, > $query_desc, $limit, $limit_cgi, $limit_desc, >@@ -568,28 +577,28 @@ like($query, qr/history/, "Order of terms doesn't matter for advanced search"); > > ( $error, $query, $simple_query, $query_cgi, > $query_desc, $limit, $limit_cgi, $limit_desc, >-$stopwords_removed, $query_type ) = buildQuery([], [ "su-br:$term" ], [ ], [ ], [], 0, 'en'); >+$stopwords_removed, $query_type ) = buildQuery([], [ "su-br($term)" ], [ ], [ ], [], 0, 'en'); > matchesExplodedTerms("Simple search for broader subjects", $query, 'Arizona', 'United States'); > > ( $error, $query, $simple_query, $query_cgi, > $query_desc, $limit, $limit_cgi, $limit_desc, >-$stopwords_removed, $query_type ) = buildQuery([], [ "su-na:$term" ], [ ], [ ], [], 0, 'en'); >+$stopwords_removed, $query_type ) = buildQuery([], [ "su-na($term)" ], [ ], [ ], [], 0, 'en'); > matchesExplodedTerms("Simple search for narrower subjects", $query, 'Arizona', 'Maricopa County', 'Navajo County', 'Pima County'); > > ( $error, $query, $simple_query, $query_cgi, > $query_desc, $limit, $limit_cgi, $limit_desc, >-$stopwords_removed, $query_type ) = buildQuery([], [ "su-rl:$term" ], [ ], [ ], [], 0, 'en'); >+$stopwords_removed, $query_type ) = buildQuery([], [ "su-rl($term)" ], [ ], [ ], [], 0, 'en'); > matchesExplodedTerms("Simple search for related subjects", $query, 'Arizona', 'United States', 'Maricopa County', 'Navajo County', 'Pima County'); > > ( $error, $query, $simple_query, $query_cgi, > $query_desc, $limit, $limit_cgi, $limit_desc, >-$stopwords_removed, $query_type ) = buildQuery([], [ "history and su-rl:$term" ], [ ], [ ], [], 0, 'en'); >+$stopwords_removed, $query_type ) = buildQuery([], [ "history && su-rl($term)" ], [ ], [ ], [], 0, 'en'); > matchesExplodedTerms("Simple search for related subjects and keyword 'history' searches related subjects", $query, 'Arizona', 'United States', 'Maricopa County', 'Navajo County', 'Pima County'); > like($query, qr/history/, "Simple search for related subjects and keyword 'history' searches for 'history'"); > > sub matchesExplodedTerms { > my ($message, $query, @terms) = @_; >- my $match = "(( or )?\\((" . join ('|', map { "su=\"$_\"" } @terms) . ")\\)){" . scalar(@terms) . "}"; >+ my $match = '(' . join ('|', map { " \@attr 1=Subject \@attr 4=1 \"$_\"" } @terms) . "){" . scalar(@terms) . "}"; > like($query, qr/$match/, $message); > } > >-- >1.7.9.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 9239
:
14020
|
14021
|
14022
|
14023
|
14172
|
14173
|
14174
|
14175
|
14180
|
14181
|
14182
|
14183
|
14847
|
14949
|
14950
|
14951
|
14952
|
14953
|
15121
|
15437
|
15865
|
15867
|
15929
|
15999
|
16004
|
16051
|
16125
|
16130
|
16131
|
16132
|
16133
|
16136
|
16140
|
16141
|
16142
|
16143
|
16144
|
16145
|
16146
|
16147
|
16148
|
16149
|
16150
|
16151
|
16152
|
16153
|
16154
|
16155
|
16180
|
16181
|
16182
| 16183 |
16184
|
16185
|
16186
|
16187
|
16188
|
16189
|
16190
|
16191
|
16192
|
16193
|
16194
|
16195