[open-ils-commits] r8063 -
trunk/Open-ILS/src/perlmods/OpenILS/Application/Search
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Nov 14 18:48:43 EST 2007
Author: erickson
Date: 2007-11-14 18:31:58 -0500 (Wed, 14 Nov 2007)
New Revision: 8063
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm
Log:
Added a new method to parse complex search query syntax for multiclass bib and metabib searches
E.g. "title:crime author:dostoyevsky lang:rus"
This will allow us to encode multiclass searches as human-readable search strings
TODO: more testing
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm 2007-11-14 20:05:15 UTC (rev 8062)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Search/Biblio.pm 2007-11-14 23:31:58 UTC (rev 8063)
@@ -9,6 +9,7 @@
use OpenSRF::Utils::SettingsClient;
use OpenILS::Utils::CStoreEditor q/:funcs/;
use OpenSRF::Utils::Cache;
+use Encode;
use OpenSRF::Utils::Logger qw/:logger/;
@@ -405,6 +406,115 @@
}
+__PACKAGE__->register_method(
+ api_name => 'open-ils.search.biblio.multiclass.query',
+ method => 'multiclass_query',
+ signature => q#
+ @param arghash @see open-ils.search.biblio.multiclass
+ @param query Raw human-readable query string.
+ Recognized search keys include:
+ keyword/kw - search keyword(s)
+ author/au/name - search author(s)
+ title/ti - search title
+ subject/su - search subject
+ series/se - search series
+ lang - limit by language (specifiy multiple langs with lang:l1 lang:l2 ...)
+ site - search at specified org unit, corresponds to actor.org_unit.shortname
+ sort - sort type (title, author, pubdate)
+ dir - sort direction (asc, desc)
+ available - if set to anything other than "false" or "0", limits to available items
+
+ keyword, title, author, subject, and series support additional search
+ subclasses, specified with a "|". For example, "title|proper:gone with the wind"
+ For more, see config.metabib_field
+
+ @param nocache @see open-ils.search.biblio.multiclass
+ #
+);
+__PACKAGE__->register_method(
+ api_name => 'open-ils.search.biblio.multiclass.query.staff',
+ method => 'multiclass_query',
+ signature => '@see open-ils.search.biblio.multiclass.query');
+__PACKAGE__->register_method(
+ api_name => 'open-ils.search.metabib.multiclass.query',
+ method => 'multiclass_query',
+ signature => '@see open-ils.search.biblio.multiclass.query');
+__PACKAGE__->register_method(
+ api_name => 'open-ils.search.metabib.multiclass.query.staff',
+ method => 'multiclass_query',
+ signature => '@see open-ils.search.biblio.multiclass.query');
+
+sub multiclass_query {
+ my($self, $conn, $arghash, $query, $docache) = @_;
+
+ $logger->debug("initial search query => $query");
+
+ $query = decode_utf8($query);
+ $query =~ s/\+/ /go;
+ $query =~ s/'//go;
+ $query =~ s/^\s+//go;
+
+ # convert convenience classes (e.g. kw for keyword) to the full class name
+ $query =~ s/kw(:|\|)/keyword$1/go;
+ $query =~ s/ti(:|\|)/title$1/go;
+ $query =~ s/au(:|\|)/author$1/go;
+ $query =~ s/su(:|\|)/subject$1/go;
+ $query =~ s/se(:|\|)/series$1/go;
+ $query =~ s/name(:|\|)/author$1/og;
+
+ $logger->debug("cleansed query string => $query");
+
+ my %search;
+
+ while ($query =~ s/((?:keyword(?:\|\w+)?|title(?:\|\w+)?|author(?:\|\w+)?|subject(?:\|\w+)?|series(?:\|\w+)?|site|dir|sort|lang|available):[^:]+)$//so) {
+ my($type, $value) = split(':', $1);
+ next unless $type and $value;
+
+ $value =~ s/^\s*//og;
+ $value =~ s/\s*$//og;
+ $type = 'sort_dir' if $type eq 'dir';
+
+ if($type eq 'site') {
+ # 'site' is the org shortname. when using this, we also want
+ # to search at the requested org's depth
+ my $e = new_editor();
+ if(my $org = $e->search_actor_org_unit({shortname => $value})->[0]) {
+ $arghash->{org_unit} = $org->id if $org;
+ $arghash->{depth} = $e->retrieve_actor_org_unit_type($org->ou_type)->depth;
+ } else {
+ $logger->warn("'site:' query used on invalid org shortname: $value ... ignoring");
+ }
+
+ } elsif($type eq 'available') {
+ # limit to available
+ $arghash->{available} = 1 unless $value eq 'false' or $value eq '0';
+
+ } elsif($type eq 'lang') {
+ # collect languages into an array of languages
+ $arghash->{language} = [] unless $arghash->{language};
+ push(@{$arghash->{language}}, $value);
+
+ } else {
+ # append the search term to the term under construction
+ $search{$type} = {} unless $search{$type};
+ $search{$type}->{term} =
+ ($search{$type}->{term}) ? $search{$type}->{term} . " $value" : $value;
+ }
+ }
+ $arghash->{searches} = \%search;
+
+ # capture the original limit because the search method alters the limit internally
+ my $ol = $arghash->{limit};
+
+ (my $method = $self->api_name) =~ s/\.query//o;
+ $method = $self->method_lookup($method);
+ my ($data) = $method->run($arghash, $docache);
+
+ $arghash->{limit} = $ol if $ol;
+ $data->{compiled_search} = $arghash;
+ return $data;
+}
+
# ----------------------------------------------------------------------------
# These are the main OPAC search methods
# ----------------------------------------------------------------------------
More information about the open-ils-commits
mailing list