Created
October 30, 2008 12:24
-
-
Save marcusramberg/20983 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package MojoMojo::Model::Search; | |
use strict; | |
use base 'Catalyst::Model'; | |
use KinoSearch::InvIndexer; | |
use KinoSearch::Searcher; | |
use KinoSearch::Analysis::PolyAnalyzer; | |
use KinoSearch::Index::Term; | |
use KinoSearch::Search::Query; | |
use KinoSearch::QueryParser::QueryParser; | |
use Data::Dumper; | |
__PACKAGE__->config->{index} ||= MojoMojo->path_to('/index'); | |
my $invindexer; | |
my $analyzer | |
= KinoSearch::Analysis::PolyAnalyzer->new( language => 'en'); | |
sub indexer { | |
my $self=shift; | |
unless ($invindexer) { | |
$invindexer ||= KinoSearch::InvIndexer->new( | |
invindex => __PACKAGE__->config->{index}, | |
create => ( -f __PACKAGE__->config->{index}.'/segments' ? 0 : 1 ), | |
analyzer => $analyzer, | |
); | |
$invindexer->spec_field(name=>'path'); | |
$invindexer->spec_field(name=>'text'); | |
$invindexer->spec_field(name=>'author'); | |
$invindexer->spec_field(name=>'date'); | |
$invindexer->spec_field(name=>'tags'); | |
} | |
return $invindexer; | |
} | |
my $searcher; | |
sub searcher { | |
my $self=shift; | |
$searcher ||= KinoSearch::Searcher->new( | |
invindex => __PACKAGE__->config->{index}, | |
analyzer => $analyzer, | |
); | |
return $searcher; | |
} | |
=item prepare_search_index | |
Create a new search index from all pages in the database. | |
Will do nothing if the index already exists. | |
=cut | |
sub prepare_search_index { | |
my $self = shift; | |
my $index = $self->indexer; | |
# is the root page already indexed? | |
return if ( $index->is_indexed('/') ); | |
MojoMojo->log->info("Initializing search index...") | |
if MojoMojo->debug; | |
# loop through all latest-version pages | |
my $count = 0; | |
my $it = MojoMojo->model('DB::Page')->search; | |
while ( my $page = $it->next ) { | |
$page->set_paths($page); | |
$self->index_page($page); | |
$count++; | |
} | |
MojoMojo->log->info("Indexed $count pages") if MojoMojo->debug; | |
} | |
=item index_page <page> | |
Create/update the search index with data from a MojoMojo page. | |
=cut | |
# updates the search index when page data changes | |
sub index_page { | |
my ( $self, $page ) = @_; | |
my $index = $self->indexer; | |
return unless ( $page && $page->content ); | |
my $content = $page->content; | |
my $key = $page->path; | |
my $text = $content->body; | |
$text .= " " . $content->abstract if ( $content->abstract ); | |
$text .= " " . $content->comments if ( $content->comments ); | |
# translate the path into plain text so we can use it in the search query later | |
my $fixed_path = $key; | |
$fixed_path =~ s{/}{X}g; | |
my $term = KinoSearch::Index::Term->new(path => $fixed_path ); | |
$index->delete_docs_by_term( $term ); | |
my $doc=$index->new_doc(); | |
$doc->set_value(author => $content->creator->login); | |
$doc->set_value(path => $fixed_path); | |
$doc->set_value(date => ( $content->created ) ? $content->created->ymd : ''); | |
$doc->set_value(tags => join( ' ', map { $_->tag } $page->tags )); | |
$doc->set_value(text => $text); | |
$index->add_doc($doc); | |
$index->finish(optimize=>1); | |
undef $invindexer; | |
} | |
sub search { | |
my ($self,$q) = @_; | |
my $qp=KinoSearch::QueryParser::QueryParser->new(analyzer=>$analyzer,fields=>['text','tags']); | |
my $query=$qp->parse($q); | |
my $hits=$self->searcher->search( query=> $query ); | |
return $hits; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment