[open-ils-commits] r15921 - trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher (miker)
svn at svn.open-ils.org
svn at svn.open-ils.org
Fri Mar 19 17:01:03 EDT 2010
Author: miker
Date: 2010-03-19 17:00:58 -0400 (Fri, 19 Mar 2010)
New Revision: 15921
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
Log:
initial perl-side implementation of QueryParser-based search
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm 2010-03-19 21:00:23 UTC (rev 15920)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm 2010-03-19 21:00:58 UTC (rev 15921)
@@ -2755,7 +2755,229 @@
api_level => 1,
);
+sub query_parser_fts {
+ my $self = shift;
+ my $client = shift;
+ my %args = shift;
+ # grab the query parser and initialize it
+ my $parser = $OpenILS::Application::Storage::QParser;
+ if (!$parser->initialization_complete) {
+ my $cstore = OpenSRF::AppSession->create( 'open-ils.cstore' );
+ $parser->initialize(
+ config_metabib_field_index_norm_map =>
+ $cstore->request(
+ 'open-ils.cstore.direct.config.metabib_field_index_norm_map.search.atomic',
+ { id => { "!=" => undef } },
+ { flesh => 1, flesh_fields => { cmfinm => [qw/norm/] }, order_by => [{ class => "cmfinm", field => "pos" }] }
+ )->gather(1),
+ search_relevance_adjustment =>
+ $cstore->request(
+ 'open-ils.cstore.direct.search.relevance_adjustment.search.atomic',
+ { id => { "!=" => undef } }
+ )->gather(1),
+ config_metabib_field =>
+ $cstore->request(
+ 'open-ils.cstore.direct.config.metabib_field.search.atomic',
+ { id => { "!=" => undef } }
+ )->gather(1),
+ );
+
+ $cstore->disconnect;
+ die("Cannot initialize $parser!") unless ($parser->initialization_complete);
+ }
+
+
+ # populate the locale/language map
+ if (!$locale_map{COMPLETE}) {
+
+ my @locales = config::i18n_locale->search_where({ code => { '<>' => '' } });
+ for my $locale ( @locales ) {
+ $locale_map{$locale->code} = $locale->marc_code;
+ }
+ $locale_map{COMPLETE} = 1;
+
+ }
+
+
+ # set the locale-based default prefered location
+ $parser->default_preferred_language( $args{preferred_language} );
+ if (!$parser->default_preferred_language) {
+ my $ses_locale = $client->session ? $client->session->session_locale : '';
+ $parser->default_preferred_language( $locale_map{ $ses_locale } );
+ }
+ $parser->default_preferred_language(
+ OpenSRF::Utils::SettingsClient->new->config_value(
+ apps => 'open-ils.storage' => app_settings => 'default_preferred_language'
+ )
+ ) if (!$parser->default_preferred_language);
+
+
+ # set the global default language multiplier
+ $parser->default_preferred_language_multiplier($args{preferred_language_weight});
+ $parser->default_preferred_language_multiplier($args{preferred_language_multiplier});
+ $parser->default_preferred_language_multiplier(
+ OpenSRF::Utils::SettingsClient->new->config_value(
+ apps => 'open-ils.storage' => app_settings => 'default_preferred_language_weight'
+ )
+ ) if (!$parser->default_preferred_language_multiplier);
+
+
+ # I hope we have a query!
+ if (! scalar( keys %{$args{query}} )) {
+ die "No search arguments were passed to ".$self->api_name;
+ }
+
+
+ # remove bad chunks of the %args hash
+ for my $bad ( grep { /^_/ } keys(%args)) {
+ delete($args{$bad});
+ }
+
+
+ # parse the query and supply any query-level %arg-based defaults
+ # we expect, and make use of, query, superpage, superpage_size, debug and core_limit args
+ my $query = $parser->new( %args );
+
+
+ # gather the site, if one is specified, defaulting to the in-query version
+ my $ou = $args{org_unit};
+ if (my $filter = $query->parse_tree->find_filter('site')) {
+ $ou = $filter->args->[0] if (@{$filter->args});
+ }
+ $ou = actor::org_unit->search( { shortname => $ou } )->next->id if ($ou and $ou !~ /^\d+$/);
+
+
+ # gather lasso, as with $ou
+ my $lasso = $args{lasso};
+ if (my $filter = $query->parse_tree->find_filter('lasso')) {
+ $lasso = $filter->args->[0] if (@{$filter->args});
+ }
+ $lasso = actor::org_lasso->search( { name => $lasso } )->next->id if ($lasso and $lasso !~ /^\d+$/);
+ $lasso = -$lasso if ($lasso);
+
+
+# # XXX once we have org_unit containers, we can make user-defined lassos .. WHEEE
+# # gather user lasso, as with $ou and lasso
+# my $mylasso = $args{my_lasso};
+# if (my $filter = $query->parse_tree->find_filter('my_lasso')) {
+# $mylasso = $filter->args->[0] if (@{$filter->args});
+# }
+# $mylasso = actor::org_unit->search( { name => $mylasso } )->next->id if ($mylasso and $mylasso !~ /^\d+$/);
+
+
+ # if we have a lasso, go with that, otherwise ... ou
+ $ou = $lasso if ($lasso);
+
+
+ # get the default $ou if we have nothing
+ $ou = actor::org_unit->search( { parent_ou => undef } )->next->id if (!$ou and !$lasso and !$mylasso);
+
+
+ # XXX when user lassos are here, check to make sure we don't have one -- it'll be passed in the depth, with an ou of 0
+ # gather the depth, if one is specified, defaulting to the in-query version
+ my $depth = $args{depth};
+ if (my $filter = $query->parse_tree->find_filter('depth')) {
+ $depth = $filter->args->[0] if (@{$filter->args});
+ }
+ $depth = actor::org_unit->search_where( [{ name => $depth },{ opac_label => $depth }], {limit => 1} )->next->id if ($depth and $depth !~ /^\d+$/);
+
+
+ # gather the limit or default to 10
+ my $limit = $args{limit} || 10;
+ if (my $filter = $query->parse_tree->find_filter('limit')) {
+ $limit = $filter->args->[0] if (@{$filter->args});
+ }
+
+
+ # gather the offset or default to 0
+ my $offset = $args{offset} || 0;
+ if (my $filter = $query->parse_tree->find_filter('offset')) {
+ $offset = $filter->args->[0] if (@{$filter->args});
+ }
+
+
+ # gather the estimation strategy or default to inclusion
+ my $estimation_strategy = $args{estimation_strategy} || 'inclusion';
+ if (my $filter = $query->parse_tree->find_filter('estimation_strategy')) {
+ $estimation_strategy = $filter->args->[0] if (@{$filter->args});
+ }
+
+
+ # gather statuses, and then forget those if we have an #available modifier
+ my @statuses;
+ if (my $filter = $query->parse_tree->find_filter('statuses')) {
+ @statuses = @{$filter->args} if (@{$filter->args});
+ }
+ @statuses = (0,7,12) if ($query->parse_tree->find_modifier('available'));
+
+
+ # gather locations
+ my @location;
+ if (my $filter = $query->parse_tree->find_filter('location')) {
+ @location = @{$filter->args} if (@{$filter->args});
+ }
+
+
+ my $param_search_ou = $ou;
+ my $param_depth = $depth; $param_depth = 'NULL' unless (defined($depth) and length($depth) > 0 );
+ my $param_core_query = $query->parse_tree->toSQL;
+ my $param_statuses = '$${' . join(',', map { s/\$//go; "\"$_\""} @statuses) . '}$$';
+ my $param_locations = '$${' . join(',', map { s/\$//go; "\"$_\""} @location) . '}$$';
+ my $staff = ($self->api_name =~ /staff/ or $query->parse_tree->find_modifier('staff')) ? "'t'" : "'f'";
+
+ my $sth = metabib::metarecord_source_map->db_Main->prepare(<<" SQL");
+ SELECT *
+ FROM search.query_parser_fts(
+ $param_search_ou\:\:INT,
+ $param_depth\:\:INT,
+ $param_core_query\:\:TEXT,
+ $param_statuses\:\:INT[],
+ $param_locations\:\:INT[],
+ $staff\:\:BOOL,
+ );
+ SQL
+
+ $sth->execute;
+
+ my $recs = $sth->fetchall_arrayref({});
+ my $summary_row = pop @$recs;
+
+ my $total = $$summary_row{total};
+ my $checked = $$summary_row{checked};
+ my $visible = $$summary_row{visible};
+ my $deleted = $$summary_row{deleted};
+ my $excluded = $$summary_row{excluded};
+
+ my $estimate = $visible;
+ if ( $total > $checked && $checked ) {
+
+ $$summary_row{hit_estimate} = FTS_paging_estimate($self, $client, $checked, $visible, $excluded, $deleted, $total);
+ $estimate = $$summary_row{estimated_hit_count} = $$summary_row{hit_estimate}{$estimation_strategy};
+
+ }
+
+ delete $$summary_row{id};
+ delete $$summary_row{rel};
+ delete $$summary_row{record};
+
+ $client->respond( $summary_row );
+
+ $log->debug("Search yielded ".scalar(@$recs)." checked, visible results with an approximate visible total of $estimate.",DEBUG);
+
+ for my $rec (@$recs[$offset .. $offset + $limit - 1]) {
+ delete $$rec{checked};
+ delete $$rec{visible};
+ delete $$rec{excluded};
+ delete $$rec{deleted};
+ delete $$rec{total};
+ $$rec{rel} = sprintf('%0.3f',$$rec{rel});
+
+ $client->respond( $rec );
+ }
+ return undef;
+}
+
1;
More information about the open-ils-commits
mailing list