File Coverage

blib/lib/KinoSearch1/Search/BooleanQuery.pm
Criterion Covered Total %
statement 84 87 96.5
branch 8 12 66.6
condition n/a
subroutine 21 23 91.3
pod 2 6 33.3
total 115 128 89.8


line stmt bran cond sub pod time code
1             package KinoSearch1::Search::BooleanQuery;
2 18     18   31820 use strict;
  18         40  
  18         1714  
3 18     18   97 use warnings;
  18         33  
  18         461  
4 18     18   665 use KinoSearch1::Util::ToolSet;
  18         44  
  18         2617  
5 18     18   101 use base qw( KinoSearch1::Search::Query );
  18         48  
  18         9309  
6              
7             BEGIN {
8 18     18   187 __PACKAGE__->init_instance_vars(
9             # constructor args / members
10             disable_coord => 0,
11             # members
12             clauses => undef,
13             max_clause_count => 1024,
14             );
15 18         158 __PACKAGE__->ready_get(qw( clauses ));
16             }
17              
18 18     18   11890 use KinoSearch1::Search::BooleanClause;
  18         56  
  18         7048  
19              
20             sub init_instance {
21 250     250 1 523 my $self = shift;
22 250         918 $self->{clauses} = [];
23             }
24              
25             # Add an subquery tagged with boolean characteristics.
26             sub add_clause {
27 524     524 1 828 my $self = shift;
28 524 50       3397 my $clause
29             = @_ == 1
30             ? shift
31             : KinoSearch1::Search::BooleanClause->new(@_);
32 524         830 push @{ $self->{clauses} }, $clause;
  524         1272  
33 524 50       1547 confess("not a BooleanClause")
34             unless a_isa_b( $clause, 'KinoSearch1::Search::BooleanClause' );
35 524         2638 confess("Too many clauses")
36 524 50       844 if @{ $self->{clauses} } > $self->{max_clause_count};
37             }
38              
39             sub get_similarity {
40 443     443 0 652 my ( $self, $searcher ) = @_;
41 443 50       1623 if ( $self->{disable_coord} ) {
42 0         0 confess "disable_coord not implemented yet";
43             }
44 443         1889 return $searcher->get_similarity;
45             }
46              
47             sub extract_terms {
48 8     8 0 12 my $self = shift;
49 8         10 my @terms;
50 8         13 for my $clause ( @{ $self->{clauses} } ) {
  8         16  
51 17         70 push @terms, $clause->get_query()->extract_terms;
52             }
53 8         35 return @terms;
54             }
55              
56             sub create_weight {
57 253     253 0 454 my ( $self, $searcher ) = @_;
58 253         2124 return KinoSearch1::Search::BooleanWeight->new(
59             parent => $self,
60             searcher => $searcher,
61             );
62              
63             }
64              
65 0     0 0 0 sub clone { shift->todo_death }
66              
67             package KinoSearch1::Search::BooleanWeight;
68 18     18   123 use strict;
  18         48  
  18         1696  
69 18     18   104 use warnings;
  18         36  
  18         751  
70 18     18   105 use KinoSearch1::Util::ToolSet;
  18         39  
  18         2656  
71 18     18   106 use base qw( KinoSearch1::Search::Weight );
  18         42  
  18         11635  
72              
73             BEGIN {
74 18     18   393 __PACKAGE__->init_instance_vars(
75             # members
76             weights => undef,
77             );
78             }
79              
80 18     18   15344 use KinoSearch1::Search::BooleanScorer;
  18         5010  
  18         8413  
81              
82             sub init_instance {
83 253     253   532 my $self = shift;
84 253         705 $self->{weights} = [];
85 253         476 my ( $weights, $searcher ) = @{$self}{ 'weights', 'searcher' };
  253         685  
86              
87 253         912 $self->{similarity} = $self->{parent}->get_similarity($searcher);
88              
89 253         638 for my $clause ( @{ $self->{parent}{clauses} } ) {
  253         923  
90 529         1903 my $query = $clause->get_query;
91 529         2119 push @$weights, $query->create_weight($searcher);
92             }
93              
94 253         894 undef $self->{searcher}; # don't want the baggage
95             }
96              
97 0     0   0 sub get_value { shift->{parent}->get_boost }
98              
99             sub sum_of_squared_weights {
100 253     253   597 my $self = shift;
101              
102 253         440 my $sum = 0;
103 253         380 $sum += $_->sum_of_squared_weights for @{ $self->{weights} };
  253         1488  
104              
105             # compound the weight of each sub-Weight
106 253         1037 $sum *= $self->{parent}->get_boost**2;
107              
108 253         845 return $sum;
109             }
110              
111             sub normalize {
112 253     253   606 my ( $self, $query_norm ) = @_;
113 253         385 $_->normalize($query_norm) for @{ $self->{weights} };
  253         1343  
114             }
115              
116             sub scorer {
117 253     253   496 my ( $self, $reader ) = @_;
118              
119 253         2172 my $scorer = KinoSearch1::Search::BooleanScorer->new(
120             similarity => $self->{similarity}, );
121              
122             # add all the subscorers one by one
123 253         622 my $clauses = $self->{parent}{clauses};
124 253         562 my $i = 0;
125 253         507 for my $weight ( @{ $self->{weights} } ) {
  253         611  
126 525         1343 my $clause = $clauses->[ $i++ ];
127 525         2011 my $subscorer = $weight->scorer($reader);
128 525 100       1396 if ( defined $subscorer ) {
    100          
129 473         1689 $scorer->add_subscorer( $subscorer, $clause->get_occur );
130             }
131             elsif ( $clause->is_required ) {
132             # if any required clause fails, the whole thing fails
133 10         167 return undef;
134             }
135             }
136 243         952 return $scorer;
137             }
138              
139             1;
140              
141             __END__