/[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

Contents of /lib/Grep/Search.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show 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 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