File Coverage

blib/lib/Plucene/Plugin/WeightedQueryParser.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Plucene::Plugin::WeightedQueryParser;
2 1     1   1880 use 5.006;
  1         4  
  1         38  
3 1     1   5 use strict;
  1         2  
  1         22  
4 1     1   4 use warnings;
  1         4  
  1         50  
5             our $VERSION = '1.0';
6 1     1   4 use base 'Plucene::QueryParser';
  1         2  
  1         1996  
7             __PACKAGE__->mk_accessors("weights");
8              
9             =head1 NAME
10              
11             Plucene::Plugin::WeightedQueryParser - Specify weights for unqualified terms
12              
13             =head1 SYNOPSIS
14              
15             use Plucene::Plugin::WeightedQueryParser;
16             my $parser = Plucene::WeightedQueryParser->new({
17             analyzer => Plucene::Plugin::Analyzer::PorterAnalyzer->new(),
18             weights => {
19             title => 5,
20             subtitle => 2,
21             body => 1
22             }
23             });
24             $parser->parse($q);
25              
26             =head1 DESCRIPTION
27              
28             Quite often, you want unqualified search terms (C) to search in
29             either the title, the body or some other part of you document. The usual
30             way to do this is to create another field, C, and throw everything
31             in that, then make that the default field for unqualified terms.
32              
33             That's fine, until you want to add different weighting for terms - so terms
34             found in the title of a document come first, then those in the subtitle,
35             then the body of the document.
36              
37             This module automatically remaps unqualified search terms, such as C
38             to C<(title:hello^5 OR subtitle:hello^2 OR body:hello^1)>, based on the
39             weights passed in to the constructor.
40              
41             =cut
42              
43             sub new {
44             my ($self, $args) = @_;
45             $args->{default} = "unused";
46             $self->SUPER::new($args);
47             }
48              
49             sub parse {
50             my ($self, $thing) = @_;
51             my $ast = $self->SUPER::parse($thing, 1);
52             # First, rebless the AST into our derived class.
53             (ref $self)->rebless($ast);
54             $ast->to_plucene($self->{weights});
55             }
56              
57             sub rebless {
58             my ($class, $t) = @_;
59             if ($t->isa("Plucene::QueryParser::Subquery")) {
60             $class->rebless($_) for @{$t->{subquery}};
61             } elsif ($t->isa("Plucene::QueryParser::TopLevel")) {
62             $class->rebless($_) for @$t;
63             }
64             my $new_class = ref $t;
65             $new_class =~ s/Plucene::QueryParser/$class/;
66             bless $t, $new_class;
67             }
68              
69             package Plucene::Plugin::WeightedQueryParser::TopLevel;
70             use base 'Plucene::QueryParser::TopLevel';
71              
72             package Plucene::Plugin::WeightedQueryParser::Subquery;
73             use base 'Plucene::QueryParser::Subquery';
74              
75             package Plucene::Plugin::WeightedQueryParser::Term;
76             use base 'Plucene::QueryParser::Term';
77             sub to_plucene {
78             my ($self, $weights) = @_;
79             return $self->SUPER::to_plucene() if exists $self->{field};
80             require Plucene::Search::BooleanQuery;
81             require Plucene::Search::BooleanClause;
82             my $query = new Plucene::Search::BooleanQuery;
83              
84             for my $field (keys %$weights) {
85             my $q = $self->SUPER::to_plucene($field);
86             $q->boost($weights->{$field});
87             $query->add_clause(Plucene::Search::BooleanClause->new({
88             prohibited => 0, required => 0, query => $q
89             }));
90             }
91             $query;
92             }
93              
94             package Plucene::Plugin::WeightedQueryParser::Phrase;
95             use base 'Plucene::QueryParser::Phrase';
96             sub to_plucene {
97             my ($self, $weights) = @_;
98             return $self->SUPER::to_plucene() if exists $self->{field};
99             require Plucene::Search::BooleanQuery;
100             require Plucene::Search::BooleanClause;
101             my $query = new Plucene::Search::BooleanQuery;
102              
103             for my $field (keys %$weights) {
104             my $q = $self->SUPER::to_plucene($field);
105             $q->boost($weights->{$field});
106             $query->add_clause(Plucene::Search::BooleanClause->new({
107             prohibited => 0, required => 0, query => $q
108             }));
109             }
110             $query;
111             }
112              
113             package Plucene::Plugin::WeightedQueryParser::Prefix;
114             use base 'Plucene::QueryParser::Prefix';
115             sub to_plucene {
116             my ($self, $weights) = @_;
117             return $self->SUPER::to_plucene() if exists $self->{field};
118             require Plucene::Search::BooleanQuery;
119             require Plucene::Search::BooleanClause;
120             my $query = new Plucene::Search::BooleanQuery;
121              
122             for my $field (keys %$weights) {
123             my $q = $self->SUPER::to_plucene($field);
124             $q->boost($weights->{$field});
125             $query->add_clause(Plucene::Search::BooleanClause->new({
126             prohibited => 0, required => 0, query => $q
127             }));
128             }
129             $query;
130             }
131              
132             1;
133              
134             =head1 AUTHOR
135              
136             Simon Cozens, C
137              
138             Development of this module was made possible by the generous sponsorship
139             of Text Matters, http://www.textmatters.com/
140              
141             This module may be distributed under the same terms as Plucene itself.
142              
143             =head1 SEE ALSO
144              
145             L.
146              
147             =cut
148              
149             1;