]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/metabib.pm
d1f85e2a677f784108bed7bf8a976b4500dd6897
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Storage / Publisher / metabib.pm
1 package OpenILS::Application::Storage::Publisher::metabib;
2 use base qw/OpenILS::Application::Storage/;
3 use vars qw/$VERSION/;
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;
10 use Data::Dumper;
11 use Digest::MD5 qw/md5_hex/;
12
13 my $log = 'OpenSRF::Utils::Logger';
14
15 $VERSION = 1;
16
17
18 sub search_full_rec {
19         my $self = shift;
20         my $client = shift;
21         my $limiters = shift;
22         my $term = shift;
23         my $window = shift;
24         $window = 100 unless (defined $window);
25
26         my $cache_key = md5_hex(Dump($limiters).$term);
27
28         my ($fts_col) = metabib::full_rec->columns('FTS');
29         my $table = metabib::full_rec->table;
30
31         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
32
33         my $fts_where = $fts->sql_where_clause();
34         my @fts_ranks = $fts->fts_rank;
35
36         my $rank = join(' + ', @fts_ranks);
37
38         my @binds;
39         my @wheres;
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);
44         }
45         my $where = join(' OR ', @wheres);
46
47         my $select = "SELECT record, sum($rank) FROM $table WHERE $where GROUP BY 1 ORDER BY 2 DESC;";
48
49         $log->debug("Search SQL :: [$select]",DEBUG);
50
51         my $recs = metabib::full_rec->db_Main->selectall_arrayref($select, {}, @binds);
52         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
53
54         $client->respond( [ @$recs[0 .. $window - 1] ] );
55
56         OpenSRF::Utils::Cache->new->put_cache( $recs );
57
58         return undef;
59
60 }
61 __PACKAGE__->register_method(
62         api_name        => 'open-ils.storage.direct.metabib.full_rec.search_fts.value',
63         method          => 'search_full_rec',
64         api_level       => 1,
65         stream          => 1,
66 );
67 __PACKAGE__->register_method(
68         api_name        => 'open-ils.storage.direct.metabib.full_rec.search_fts.index_vector',
69         method          => 'search_full_rec',
70         api_level       => 1,
71         stream          => 1,
72 );
73
74 sub search_class_fts {
75         my $self = shift;
76         my $client = shift;
77         my $term = shift;
78         my $ou = shift;
79         my $ou_type = shift;
80         my $window = shift;
81         $window = 100 unless (defined $window);
82         
83
84         (my $class = $self->api_name) =~ s/.*metabib.(\w+).search_fts.*/$1/o;
85         my $cache_key = md5_hex($class.$term.$ou.$ou_type);
86
87         $log->debug("Cache key for $class search of '$term' at ($ou,$ou_type) will be $cache_key", DEBUG);
88
89         my $descendants = defined($ou_type) ?
90                                 "actor.org_unit_descendants($ou, $ou_type)" :
91                                 "actor.org_unit_descendants($ou)";
92
93         my $class = $self->{cdbi};
94         my $table = $class->table;
95
96         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
97
98         my $fts_where = $fts->sql_where_clause;
99         my @fts_ranks = $fts->fts_rank;
100
101         my $rank = join(' + ', @fts_ranks);
102
103         my $select = <<"        SQL";
104                 SELECT  m.metarecord, sum($rank)/count(m.source)
105                   FROM  $table f,
106                         metabib.metarecord_source_map m,
107                         asset.call_number cn,
108                         $descendants d
109                   WHERE $fts_where
110                         AND m.source = f.source
111                         AND cn.record = m.source
112                         AND cn.owning_lib = d.id
113                   GROUP BY 1
114                   ORDER BY 2 DESC;
115         SQL
116
117         $log->debug("Field Search SQL :: [$select]",DEBUG);
118
119         my $recs = $class->db_Main->selectall_arrayref($select);
120         
121         $log->debug("Search yielded ".scalar(@$recs)." results.",DEBUG);
122
123         $client->respond( [ @$recs[0 .. $window - 1] ] );
124
125         OpenSRF::Utils::Cache->new->put_cache( $recs );
126
127         return undef;
128
129 }
130 __PACKAGE__->register_method(
131         api_name        => 'open-ils.storage.metabib.title.search_fts.metarecord',
132         method          => 'search_class_fts',
133         api_level       => 1,
134         stream          => 1,
135         cdbi            => 'metabib::title_field_entry',
136 );
137 __PACKAGE__->register_method(
138         api_name        => 'open-ils.storage.metabib.author.search_fts.metarecord',
139         method          => 'search_class_fts',
140         api_level       => 1,
141         stream          => 1,
142         cdbi            => 'metabib::author_field_entry',
143 );
144 __PACKAGE__->register_method(
145         api_name        => 'open-ils.storage.metabib.subject.search_fts.metarecord',
146         method          => 'search_class_fts',
147         api_level       => 1,
148         stream          => 1,
149         cdbi            => 'metabib::subject_field_entry',
150 );
151 __PACKAGE__->register_method(
152         api_name        => 'open-ils.storage.metabib.keyword.search_fts.metarecord',
153         method          => 'search_class_fts',
154         api_level       => 1,
155         stream          => 1,
156         cdbi            => 'metabib::keyword_field_entry',
157 );
158
159 sub search_class_fts_count {
160         my $self = shift;
161         my $client = shift;
162         my $term = shift;
163         my $ou = shift;
164         my $ou_type = shift;
165
166         my $descendants = defined($ou_type) ?
167                                 "actor.org_unit_descendants($ou, $ou_type)" :
168                                 "actor.org_unit_descendants($ou)";
169                 
170
171         my $class = $self->{cdbi};
172         my $table = $class->table;
173
174         my $fts = OpenILS::Application::Storage::FTS->compile($term, 'value','index_vector');
175
176         my $fts_where = $fts->sql_where_clause;
177
178         # XXX test an "EXISTS version of descendant checking...
179         my $select = <<"        SQL";
180                 SELECT  count(distinct  m.metarecord)
181                   FROM  $table f,
182                         metabib.metarecord_source_map m,
183                         asset.call_number cn,
184                         $descendants d
185                   WHERE $fts_where
186                         AND m.source = f.source
187                         AND cn.record = m.source
188                         AND cn.owning_lib = d.id;
189         SQL
190
191         $log->debug("Field Search Count SQL :: [$select]",DEBUG);
192
193         my $recs = $class->db_Main->selectrow_arrayref($select)->[0];
194         
195         $log->debug("Count Search yielded $recs results.",DEBUG);
196
197         return $recs;
198
199 }
200 __PACKAGE__->register_method(
201         api_name        => 'open-ils.storage.metabib.title.search_fts.metarecord_count',
202         method          => 'search_class_fts_count',
203         api_level       => 1,
204         stream          => 1,
205         cdbi            => 'metabib::title_field_entry',
206 );
207 __PACKAGE__->register_method(
208         api_name        => 'open-ils.storage.metabib.author.search_fts.metarecord_count',
209         method          => 'search_class_fts_count',
210         api_level       => 1,
211         stream          => 1,
212         cdbi            => 'metabib::author_field_entry',
213 );
214 __PACKAGE__->register_method(
215         api_name        => 'open-ils.storage.metabib.subject.search_fts.metarecord_count',
216         method          => 'search_class_fts_count',
217         api_level       => 1,
218         stream          => 1,
219         cdbi            => 'metabib::subject_field_entry',
220 );
221 __PACKAGE__->register_method(
222         api_name        => 'open-ils.storage.metabib.keyword.search_fts.metarecord_count',
223         method          => 'search_class_fts_count',
224         api_level       => 1,
225         stream          => 1,
226         cdbi            => 'metabib::keyword_field_entry',
227 );
228
229 1;