1 package OpenILS::Application::Storage::Publisher::metabib;
2 use base qw/OpenILS::Application::Storage/;
4 use OpenSRF::EX qw/:try/;
5 use OpenILS::Application::Storage::CDBI::metabib;
6 use OpenILS::Application::Storage::FTS;
7 use OpenILS::Utils::Fieldmapper;
8 use OpenSRF::Utils::Logger qw/:level/;
9 use OpenSRF::Utils::Cache;
11 use Digest::MD5 qw/md5_hex/;
13 my $log = 'OpenSRF::Utils::Logger';
24 $window = 100 unless (defined $window);
26 my $cache_key = md5_hex(Dump($limiters).$term);
28 my ($fts_col) = metabib::full_rec->columns('FTS');
29 my $table = metabib::full_rec->table;
31 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
33 my $fts_where = $fts->sql_where_clause();
34 my @fts_ranks = $fts->fts_rank;
36 my $rank = join(' + ', @fts_ranks);
40 for my $limit (@$limiters) {
41 push @wheres, "( tag = ? AND subfield LIKE ? AND $fts_where )";
42 push @binds, $$limit{tag}, $$limit{subfield};
43 $log->debug("Limiting query using { tag => $$limit{tag}, subfield => $$limit{subfield} }", DEBUG);
45 my $where = join(' OR ', @wheres);
47 my $select = "SELECT record, sum($rank) FROM $table WHERE $where GROUP BY 1 ORDER BY 2 DESC;";
49 $log->debug("Search SQL :: [$select]",DEBUG);
51 my $recs = metabib::full_rec->db_Main->selectall_arrayref($select, {}, @binds);
52 $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
54 $client->respond( [ @$recs[0 .. $window - 1] ] );
56 OpenSRF::Utils::Cache->new->put_cache( $recs );
61 __PACKAGE__->register_method(
62 api_name => 'open-ils.storage.direct.metabib.full_rec.search_fts.value',
63 method => 'search_full_rec',
67 __PACKAGE__->register_method(
68 api_name => 'open-ils.storage.direct.metabib.full_rec.search_fts.index_vector',
69 method => 'search_full_rec',
74 sub search_class_fts {
81 $window = 100 unless (defined $window);
84 (my $class = $self->api_name) =~ s/.*metabib.(\w+).search_fts.*/$1/o;
85 my $cache_key = md5_hex($class.$term.$ou.$ou_type);
87 $log->debug("Cache key for $class search of '$term' at ($ou,$ou_type) will be $cache_key", DEBUG);
89 my $descendants = defined($ou_type) ?
90 "actor.org_unit_descendants($ou, $ou_type)" :
91 "actor.org_unit_descendants($ou)";
93 my $class = $self->{cdbi};
94 my $table = $class->table;
96 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
98 my $fts_where = $fts->sql_where_clause;
99 my @fts_ranks = $fts->fts_rank;
101 my $rank = join(' + ', @fts_ranks);
103 my $select = <<" SQL";
104 SELECT m.metarecord, sum($rank)/count(m.source)
106 metabib.metarecord_source_map m,
107 asset.call_number cn,
110 AND m.source = f.source
111 AND cn.record = m.source
112 AND cn.owning_lib = d.id
117 $log->debug("Field Search SQL :: [$select]",DEBUG);
119 my $recs = $class->db_Main->selectall_arrayref($select);
121 $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
123 $client->respond( [ @$recs[0 .. $window - 1] ] );
125 OpenSRF::Utils::Cache->new->put_cache( $recs );
130 __PACKAGE__->register_method(
131 api_name => 'open-ils.storage.metabib.title.search_fts.metarecord',
132 method => 'search_class_fts',
135 cdbi => 'metabib::title_field_entry',
137 __PACKAGE__->register_method(
138 api_name => 'open-ils.storage.metabib.author.search_fts.metarecord',
139 method => 'search_class_fts',
142 cdbi => 'metabib::author_field_entry',
144 __PACKAGE__->register_method(
145 api_name => 'open-ils.storage.metabib.subject.search_fts.metarecord',
146 method => 'search_class_fts',
149 cdbi => 'metabib::subject_field_entry',
151 __PACKAGE__->register_method(
152 api_name => 'open-ils.storage.metabib.keyword.search_fts.metarecord',
153 method => 'search_class_fts',
156 cdbi => 'metabib::keyword_field_entry',
159 sub search_class_fts_count {
166 my $descendants = defined($ou_type) ?
167 "actor.org_unit_descendants($ou, $ou_type)" :
168 "actor.org_unit_descendants($ou)";
171 my $class = $self->{cdbi};
172 my $table = $class->table;
174 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
176 my $fts_where = $fts->sql_where_clause;
178 # XXX test an "EXISTS version of descendant checking...
179 my $select = <<" SQL";
180 SELECT count(distinct m.metarecord)
182 metabib.metarecord_source_map m,
183 asset.call_number cn,
186 AND m.source = f.source
187 AND cn.record = m.source
188 AND cn.owning_lib = d.id;
191 $log->debug("Field Search Count SQL :: [$select]",DEBUG);
193 my $recs = $class->db_Main->selectrow_arrayref($select)->[0];
195 $log->debug("Count Search yielded $recs results.",DEBUG);
200 __PACKAGE__->register_method(
201 api_name => 'open-ils.storage.metabib.title.search_fts.metarecord_count',
202 method => 'search_class_fts_count',
205 cdbi => 'metabib::title_field_entry',
207 __PACKAGE__->register_method(
208 api_name => 'open-ils.storage.metabib.author.search_fts.metarecord_count',
209 method => 'search_class_fts_count',
212 cdbi => 'metabib::author_field_entry',
214 __PACKAGE__->register_method(
215 api_name => 'open-ils.storage.metabib.subject.search_fts.metarecord_count',
216 method => 'search_class_fts_count',
219 cdbi => 'metabib::subject_field_entry',
221 __PACKAGE__->register_method(
222 api_name => 'open-ils.storage.metabib.keyword.search_fts.metarecord_count',
223 method => 'search_class_fts_count',
226 cdbi => 'metabib::keyword_field_entry',