/[Grep]/lib/Grep/Search.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /lib/Grep/Search.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (hide annotations)
Wed Feb 21 03:04:48 2007 UTC (17 years, 2 months ago) by dpavlin
File size: 3232 byte(s)
use real full-text search engine (Lucene in this case) for Search action,
added Grep::Search helper object
1 dpavlin 47 package Grep::Search;
2    
3     use strict;
4     use warnings;
5    
6     use Data::Dump qw/dump/;
7     use Lucene;
8     use Jifty::Util;
9    
10     my $index_path = Jifty::Util->app_root . '/var/lucene';
11    
12     my ( $analyzer, $store, $writer );
13    
14     my $debug = 0;
15    
16     sub reopen_index {
17     my $self = shift;
18    
19     $analyzer ||= new Lucene::Analysis::Standard::StandardAnalyzer();
20     my $create = 0;
21     if (! -e "$index_path/segments") {
22     $create = 1;
23     Jifty->log->debug("creating index $index_path") unless ($store);
24     } else {
25     Jifty->log->debug("using index: $index_path") unless ($store);
26     }
27     $store ||= Lucene::Store::FSDirectory->getDirectory( $index_path, $create );
28     }
29    
30     =head2 add
31    
32     Grep::Search->add( $record );
33    
34     =cut
35    
36     sub add {
37     my $self = shift;
38    
39     my $i = shift or die "no record to add";
40    
41     die "record not Jifty::Record but ", ref $i unless ($i->isa('Jifty::Record'));
42    
43     $self->reopen_index;
44    
45     $writer ||= new Lucene::Index::IndexWriter( $store, $analyzer, 0 );
46    
47     my $pk = { $i->primary_keys };
48    
49     my $doc = new Lucene::Document;
50    
51     my @columns = map { $_->name } $i->columns;
52    
53     foreach my $c ( @columns ) {
54    
55     my $v = $i->$c;
56    
57     if ( ref($v) ne '' ) {
58     if ($i->$c->can('id')) {
59     $v = $i->$c->id;
60     warn " # $c = $v [id]\n" if ($debug);
61     $doc->add(Lucene::Document::Field->Keyword( $c, $v ));
62     } elsif ($v->isa('Jifty::DateTime')) {
63     warn " d $c = $v\n" if ($debug);
64     $doc->add(Lucene::Document::Field->Keyword( $c, "$v" ));
65     } else {
66     warn " s $c = $v [",ref($v),"]\n" if ($debug);
67     }
68     next;
69     }
70    
71     next if (! defined($v) || $v eq '');
72    
73     $v =~ s/<[^>]+>/ /gs;
74    
75     if ( defined( $pk->{$c} ) ) {
76     $doc->add(Lucene::Document::Field->Keyword( $c, $v ));
77     warn " * $c = $v\n" if ($debug);
78     } else {
79     $doc->add(Lucene::Document::Field->Text( $c, $v ));
80     warn " + $c = $v\n" if ($debug);
81     }
82     }
83    
84     $writer->addDocument($doc);
85    
86     Jifty->log->debug("added ", $i->id, " to index");
87     }
88    
89     =head2
90    
91     my $ItemCollection = Grep::Search->collection( 'search query' );
92    
93     =cut
94    
95     sub collection {
96     my $self = shift;
97    
98     my $q = shift or die "no q?";
99    
100     $self->reopen_index;
101    
102     my $searcher = new Lucene::Search::IndexSearcher($store);
103     my $parser = new Lucene::QueryParser("content", $analyzer);
104     my $query = $parser->parse( $q );
105    
106     Jifty->log->debug("searching for '$q'");
107    
108     my $hits = $searcher->search($query);
109     my $num_hits = $hits->length();
110    
111     Jifty->log->debug("found $num_hits results");
112    
113     my $collection = Grep::Model::ItemCollection->new();
114    
115     my @results;
116    
117     for ( my $i = 0; $i < $num_hits; $i++ ) {
118    
119     my $doc = $hits->doc( $i );
120    
121     my $score = $hits->score($i);
122     my $title = $doc->get("title");
123     my $id = $doc->get("id");
124    
125     warn "## $i $score $title\n";
126    
127     my $item = Grep::Model::Item->new();
128     my ($ok,$msg) = $item->load_by_cols( id => $id );
129    
130     if ( $ok ) {
131     $collection->add_record( $item );
132     } else {
133     warn "can't load item $id\n";
134     }
135    
136     }
137    
138     undef $hits;
139     undef $query;
140     undef $parser;
141     undef $searcher;
142    
143     return $collection;
144     }
145    
146     =head2 finish
147    
148     Grep::Search->finish
149    
150     =cut
151    
152     sub finish {
153     my $self = shift;
154     if ($writer) {
155     warn "closing index\n";
156     $writer->close;
157     }
158     undef $writer;
159     }
160    
161     sub _signal {
162     my $s = shift;
163     warn "catched SIG $s\n";
164     finish();
165     exit(0);
166     }
167    
168     $SIG{'__DIE__'} = \&_signal;
169     $SIG{'INT'} = \&_signal;
170     $SIG{'QUIT'} = \&_signal;
171    
172     1;

  ViewVC Help
Powered by ViewVC 1.1.26