1 package OpenILS::Application::Storage::Publisher::metabib;
2 use base qw/OpenILS::Application::Storage::Publisher/;
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 my $term = $args{term};
25 my $limiters = $args{restrict};
27 my ($index_col) = metabib::full_rec->columns('FTS');
28 $index_col ||= 'value';
29 my $search_table = metabib::full_rec->table;
31 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value',"$index_col");
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 $search_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($_) for (@$recs);
57 __PACKAGE__->register_method(
58 api_name => 'open-ils.storage.direct.metabib.full_rec.search_fts.value',
59 method => 'search_full_rec',
64 __PACKAGE__->register_method(
65 api_name => 'open-ils.storage.direct.metabib.full_rec.search_fts.index_vector',
66 method => 'search_full_rec',
73 # XXX factored most of the PG dependant stuff out of here... need to find a way to do "dependants".
74 sub search_class_fts {
79 my $term = $args{term};
80 my $ou = $args{org_unit};
81 my $ou_type = $args{depth};
84 my $descendants = defined($ou_type) ?
85 "actor.org_unit_descendants($ou, $ou_type)" :
86 "actor.org_unit_descendants($ou)";
88 my $class = $self->{cdbi};
89 my $search_table = $class->table;
91 my $metabib_metarecord_source_map_table = metabib::metarecord_source_map->table;
92 my $asset_call_number_table = asset::call_number->table;
94 my ($index_col) = $class->columns('FTS');
95 $index_col ||= 'value';
97 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value', "$index_col");
99 my $fts_where = $fts->sql_where_clause;
100 my @fts_ranks = $fts->fts_rank;
102 my $rank = join(' + ', @fts_ranks);
104 my $select = <<" SQL";
105 SELECT m.metarecord, sum($rank)/count(m.source)
106 FROM $search_table f,
107 $metabib_metarecord_source_map_table m,
108 $asset_call_number_table cn,
111 AND m.source = f.source
112 AND cn.record = m.source
113 AND cn.owning_lib = d.id
118 $log->debug("Field Search SQL :: [$select]",DEBUG);
120 my $recs = $class->db_Main->selectall_arrayref($select);
122 $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
124 $client->respond($_) for (@$recs);
127 __PACKAGE__->register_method(
128 api_name => 'open-ils.storage.metabib.title.search_fts.metarecord',
129 method => 'search_class_fts',
132 cdbi => 'metabib::title_field_entry',
135 __PACKAGE__->register_method(
136 api_name => 'open-ils.storage.metabib.author.search_fts.metarecord',
137 method => 'search_class_fts',
140 cdbi => 'metabib::author_field_entry',
143 __PACKAGE__->register_method(
144 api_name => 'open-ils.storage.metabib.subject.search_fts.metarecord',
145 method => 'search_class_fts',
148 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',
160 # XXX factored most of the PG dependant stuff out of here... need to find a way to do "dependants".
161 sub search_class_fts_count {
166 my $term = $args{term};
167 my $ou = $args{org_unit};
168 my $ou_type = $args{depth};
169 my $limit = $args{limit} || 100;
170 my $offset = $args{offset} || 0;
172 my $descendants = defined($ou_type) ?
173 "actor.org_unit_descendants($ou, $ou_type)" :
174 "actor.org_unit_descendants($ou)";
177 (my $search_class = $self->api_name) =~ s/.*metabib.(\w+).search_fts.*/$1/o;
178 my $cache_key = md5_hex($search_class.$term.$ou.$ou_type.'_COUNT_');
180 my $cached_recs = OpenSRF::Utils::Cache->new->get_cache( $cache_key );
181 return $cached_recs if (defined $cached_recs);
183 my $class = $self->{cdbi};
184 my $search_table = $class->table;
186 my $metabib_metarecord_source_map_table = metabib::metarecord_source_map->table;
187 my $asset_call_number_table = asset::call_number->table;
189 my ($index_col) = $class->columns('FTS');
190 $index_col ||= 'value';
192 my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value',"$index_col");
194 my $fts_where = $fts->sql_where_clause;
196 # XXX test an "EXISTS version of descendant checking...
197 my $select = <<" SQL";
198 SELECT count(distinct m.metarecord)
199 FROM $search_table f,
200 $metabib_metarecord_source_map_table m,
201 $asset_call_number_table cn,
204 AND m.source = f.source
205 AND cn.record = m.source
206 AND cn.owning_lib = d.id;
209 $log->debug("Field Search Count SQL :: [$select]",DEBUG);
211 my $recs = $class->db_Main->selectrow_arrayref($select)->[0];
213 $log->debug("Count Search yielded $recs results.",DEBUG);
215 OpenSRF::Utils::Cache->new->put_cache( $cache_key => $recs );
220 __PACKAGE__->register_method(
221 api_name => 'open-ils.storage.metabib.title.search_fts.metarecord_count',
222 method => 'search_class_fts_count',
225 cdbi => 'metabib::title_field_entry',
228 __PACKAGE__->register_method(
229 api_name => 'open-ils.storage.metabib.author.search_fts.metarecord_count',
230 method => 'search_class_fts_count',
233 cdbi => 'metabib::author_field_entry',
236 __PACKAGE__->register_method(
237 api_name => 'open-ils.storage.metabib.subject.search_fts.metarecord_count',
238 method => 'search_class_fts_count',
241 cdbi => 'metabib::subject_field_entry',
244 __PACKAGE__->register_method(
245 api_name => 'open-ils.storage.metabib.keyword.search_fts.metarecord_count',
246 method => 'search_class_fts_count',
249 cdbi => 'metabib::keyword_field_entry',