File Coverage

blib/lib/PGXN/API/Searcher.pm
Criterion Covered Total %
statement 45 47 95.7
branch 3 4 75.0
condition 6 6 100.0
subroutine 11 13 84.6
pod 4 4 100.0
total 69 74 93.2


line stmt bran cond sub pod time code
1             package PGXN::API::Searcher;
2              
3 1     1   137314 use 5.10.0;
  1         2  
4 1     1   7 use utf8;
  1         2  
  1         18  
5 1     1   47 use File::Spec;
  1         3  
  1         40  
6 1     1   433 use Lucy::Search::QueryParser;
  1         143  
  1         34  
7 1     1   439 use Lucy::Search::IndexSearcher;
  1         133  
  1         32  
8 1     1   412 use Lucy::Highlight::Highlighter;
  1         125  
  1         28  
9 1     1   4 use Carp;
  1         1  
  1         527  
10              
11             our $VERSION = 'v0.11.1';
12              
13             sub new {
14 1     1 1 319029 my ($class, $path) = @_;
15 1         4 my %parsers;
16 1         5 for my $iname (qw(docs dists extensions users tags)) {
17 5         2197 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         4326 $p->set_heed_colons(1); # XXX Soon to be deprecated.
23             }
24             bless {
25 1         13 doc_root => $path,
26             parsers => \%parsers,
27             } => $class;
28             }
29              
30 13     13 1 5994 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 12     12 1 3964 my ($self, %params) = @_;
51 12   100     54 my $iname = $params{in} || 'docs';
52 12         1328 my $query = $self->{parsers}{$iname}->parse($params{query});
53 12 100 100     123 my $limit = ($params{limit} ||= 50) < 1024 ? $params{limit} : 50;
54 12         37 my $searcher = Lucy::Search::IndexSearcher->new(
55             index => File::Spec->catdir($self->doc_root, '_index', $iname)
56             );
57              
58             my $hits = $searcher->hits(
59             query => $query,
60             offset => $params{offset},
61 12         13611 num_wanted => $limit,
62             );
63              
64             # Arrange for highlighted excerpts to be created.
65 12         52 my $highlighter;
66 12 50       58 if (my $field = $highlightable{$iname}) {
67 12         863 my $h = Lucy::Highlight::Highlighter->new(
68             searcher => $searcher,
69             query => $query,
70             field => $field,
71             );
72             $highlighter = sub {
73 13     13   708 return excerpt => $h->create_excerpt(shift);
74 12         116 };
75             } else {
76 0     0   0 $highlighter = sub { };
77             }
78              
79             my %ret = (
80             query => $params{query},
81 12   100     206 offset => $params{offset} || 0,
82             limit => $limit,
83             count => $hits->total_hits,
84             hits => my $res = [],
85             );
86              
87             # Create result list.
88 12         341 while ( my $hit = $hits->next ) {
89 13         149 push @{ $res } => {
90             score => sprintf( "%0.3f", $hit->get_score ),
91             $highlighter->($hit),
92 13         29 map { $_ => $hit->{$_} } @{ $fields{$iname} }
  83         612  
  13         64  
93             };
94             }
95              
96 12         1760 return \%ret;
97             }
98              
99             1;
100              
101             __END__