File Coverage

blib/lib/Plucene/Search/Hits.pm
Criterion Covered Total %
statement 46 51 90.2
branch 7 10 70.0
condition 3 6 50.0
subroutine 10 11 90.9
pod 4 4 100.0
total 70 82 85.3


line stmt bran cond sub pod time code
1             package Plucene::Search::Hits;
2              
3             =head1 NAME
4              
5             Plucene::Search::Hits - A list of ranked documents
6              
7             =head1 SYNOPSIS
8              
9             my $hits = Plucene::Search::Hits->new;
10              
11             my $doc = $hits->doc($n);
12             my $score = $hits->score($n);
13             my $hit_doc = $hits->hit_doc($n);
14            
15             =head1 DESCRIPTION
16              
17             This is a list of ranked documents, used to hold search results.
18              
19             =head1 METHODS
20              
21             =cut
22              
23 16     16   90 use strict;
  16         35  
  16         550  
24 16     16   196 use warnings;
  16         37  
  16         460  
25              
26 16     16   106 use Carp qw/croak/;
  16         305  
  16         1299  
27              
28 16     16   91 use Plucene::Search::TopDocs;
  16         31  
  16         531  
29              
30 16     16   473 use base 'Class::Accessor::Fast';
  16         31  
  16         10207  
31             __PACKAGE__->mk_accessors(
32             qw/ query searcher filter length hit_docs
33             first last num_docs max_docs /
34             );
35              
36             =head2 new
37              
38             my $hits = Plucene::Search::Hits->new;
39              
40             =head2 query / searcher / filter / length / hit_docs / first /
41             last / num_docs / max_docs
42              
43             Get / set these attributes.
44              
45             =cut
46              
47             sub new {
48 176     176 1 871 my $self = shift->SUPER::new(@_);
49 176         2642 $self->num_docs(0);
50 176         1483 $self->max_docs(200);
51 176         1378 $self->hit_docs([]);
52 176         1320 $self->_get_more_hits(50);
53 176         4321 return $self;
54             }
55              
56             sub _get_more_hits {
57 176     176   451 my ($self, $min) = @_;
58 176 50       547 if (@{ $self->{hit_docs} } > $min) { $min = @{ $self->{hit_docs} }; }
  176         962  
  0         0  
  0         0  
59 176         501 my $n = $min * 2;
60 176         785 my $top_docs = $self->searcher->search_top($self->query, $self->filter, $n);
61 176         10990 $self->length($top_docs->total_hits);
62              
63 176         2973 my @score_docs = $top_docs->score_docs;
64              
65 176         420 my $score_norm = 1.0;
66 176 100 100     556 $score_norm = 1 / $score_docs[0]->{score}
67             if $self->length > 0
68             and $score_docs[0]->{score} > 1.0;
69              
70 176 50       2679 my $end = $#score_docs < $self->length ? $#score_docs : $self->length;
71 176         1376 for my $score_doc (@score_docs[ @{ $self->{hit_docs} } .. $end ]) {
  176         974  
72 259         1182 push @{ $self->{hit_docs} },
  259         2392  
73             Plucene::Search::HitDoc->new({
74             score => $score_doc->{score} * $score_norm,
75             id => $score_doc->{doc},
76             });
77             }
78             }
79              
80             =head2 doc
81              
82             my $doc = $hits->doc($n);
83              
84             Returns the nth document.
85            
86             =cut
87              
88             sub doc {
89 0     0 1 0 my ($self, $n) = @_;
90 0         0 my $hit = $self->hit_doc($n);
91              
92             # Not sure we need the LRU for now
93              
94 0   0     0 return $hit->doc || $hit->doc($self->searcher->doc($hit->id));
95             }
96              
97             =head2 score
98              
99             my $score = $hits->score($n);
100              
101             The score of the nth document.
102            
103             =cut
104              
105             sub score {
106 1     1 1 549 my ($self, $n) = @_;
107 1         4 return $self->hit_doc($n)->score;
108             }
109              
110             =head2 hit_doc
111              
112             my $hit_doc = $hits->hit_doc($n);
113              
114             Returns the nth hit document.
115              
116             =cut
117              
118             sub hit_doc {
119 2     2 1 556 my ($self, $n) = @_;
120 2 100       8 if ($n >= $self->length) {
121 1         229 croak("Not a valid hit number: $n");
122             }
123 1 50       6 $self->_get_more_hits($n) if $n >= @{ $self->{hit_docs} };
  1         5  
124 1         7 return $self->{hit_docs}[$n];
125             }
126              
127             package Plucene::Search::HitDoc;
128              
129 16     16   103 use base 'Class::Accessor::Fast';
  16         41  
  16         1611  
130              
131             __PACKAGE__->mk_accessors(qw/score id doc/);
132              
133             1;