File Coverage

blib/lib/PGXN/API/Searcher.pm
Criterion Covered Total %
statement 46 49 93.8
branch 3 4 75.0
condition 6 6 100.0
subroutine 11 13 84.6
pod 4 4 100.0
total 70 76 92.1


line stmt bran cond sub pod time code
1             package PGXN::API::Searcher;
2              
3 2     2   125445 use 5.10.0;
  2         9  
  2         662  
4 2     2   1193 use utf8;
  2         13  
  2         15  
5 2     2   54 use File::Spec;
  2         8  
  2         49  
6 2     2   1829 use Lucy::Search::QueryParser;
  2         43745  
  2         64  
7 2     2   2328 use Lucy::Search::IndexSearcher;
  2         310  
  2         77  
8 2     2   2262 use Lucy::Highlight::Highlighter;
  2         336  
  2         78  
9 2     2   16 use Carp;
  2         3  
  2         1675  
10              
11             our $VERSION = v0.10.1;
12              
13             sub new {
14 1     1 1 76822 my ($class, $path) = @_;
15 1         3 my %parsers;
16 1         4 for my $iname (qw(docs dists extensions users tags)) {
17 5         150 my $p = $parsers{$iname} = Lucy::Search::QueryParser->new(
18             schema => Lucy::Search::IndexSearcher->new(
19             index => File::Spec->catdir($path, '_index', $iname)
20             )->get_schema,
21             );
22 5         6302 $p->set_heed_colons(1); # XXX Soon to be deprecated.
23             }
24             bless {
25 1         27 doc_root => $path,
26             parsers => \%parsers,
27             } => $class;
28             }
29              
30 11     11 1 1029 sub doc_root { shift->{doc_root} }
31 0     0 1 0 sub parsers { shift->{parsers} }
32              
33             my %highlightable = (
34             docs => 'body',
35             dists => 'readme',
36             extensions => 'abstract',
37             users => 'details',
38             tags => undef,
39             );
40              
41             my %fields = (
42             docs => [qw(title abstract dist version docpath date user user_name)],
43             dists => [qw(dist version abstract date user user_name)],
44             extensions => [qw(extension abstract dist version docpath date user user_name)],
45             users => [qw(user name uri)],
46             tags => [qw(tag)],
47             );
48              
49             sub search {
50 10     10 1 17192 my ($self, %params) = @_;
51 10   100     74 my $iname = $params{in} || 'docs';
52 10         1424 my $query = $self->{parsers}{$iname}->parse($params{query});
53 10 100 100     94 my $limit = ($params{limit} ||= 50) < 1024 ? $params{limit} : 50;
54 10         50 my $searcher = Lucy::Search::IndexSearcher->new(
55             index => File::Spec->catdir($self->doc_root, '_index', $iname)
56             );
57              
58 10         17790 my $hits = $searcher->hits(
59             query => $query,
60             offset => $params{offset},
61             num_wanted => $limit,
62             );
63              
64             # Arrange for highlighted excerpts to be created.
65 10         111 my $highlighter;
66 10 50       54 if (my $field = $highlightable{$iname}) {
67 10         563 my $h = Lucy::Highlight::Highlighter->new(
68             searcher => $searcher,
69             query => $query,
70             field => $field,
71             );
72             $highlighter = sub {
73 13     13   1158 return excerpt => $h->create_excerpt(shift);
74 10         63 };
75             } else {
76 0     0   0 $highlighter = sub { };
  0         0  
77             }
78              
79 10   100     181 my %ret = (
80             query => $params{query},
81             offset => $params{offset} || 0,
82             limit => $limit,
83             count => $hits->total_hits,
84             hits => my $res = [],
85             );
86              
87             # Create result list.
88 10         444 while ( my $hit = $hits->next ) {
89 13         292 push @{ $res } => {
  83         644  
90             score => sprintf( "%0.3f", $hit->get_score ),
91             $highlighter->($hit),
92 13         25 map { $_ => $hit->{$_} } @{ $fields{$iname} }
  13         49  
93             };
94             }
95              
96 10         34736 return \%ret;
97             }
98              
99             1;
100              
101             __END__