--- trunk/Estraier.pm 2006/01/07 16:19:31 63 +++ trunk/Estraier.pm 2006/05/08 21:33:37 132 @@ -4,7 +4,7 @@ use strict; use warnings; -our $VERSION = '0.01'; +our $VERSION = '0.06_1'; =head1 NAME @@ -12,8 +12,65 @@ =head1 SYNOPSIS - use Search::Estraier; - my $est = new Search::Estraier(); +=head2 Simple indexer + + use Search::Estraier; + + # create and configure node + my $node = new Search::Estraier::Node( + url => 'http://localhost:1978/node/test', + user => 'admin', + passwd => 'admin' + ); + + # create document + my $doc = new Search::Estraier::Document; + + # add attributes + $doc->add_attr('@uri', "http://estraier.gov/example.txt"); + $doc->add_attr('@title', "Over the Rainbow"); + + # add body text to document + $doc->add_text("Somewhere over the rainbow. Way up high."); + $doc->add_text("There's a land that I heard of once in a lullaby."); + + die "error: ", $node->status,"\n" unless (eval { $node->put_doc($doc) }); + +=head2 Simple searcher + + use Search::Estraier; + + # create and configure node + my $node = new Search::Estraier::Node( + url => 'http://localhost:1978/node/test', + user => 'admin', + passwd => 'admin', + croak_on_error => 1, + ); + + # create condition + my $cond = new Search::Estraier::Condition; + + # set search phrase + $cond->set_phrase("rainbow AND lullaby"); + + my $nres = $node->search($cond, 0); + + if (defined($nres)) { + print "Got ", $nres->hits, " results\n"; + + # for each document in results + for my $i ( 0 ... $nres->doc_num - 1 ) { + # get result document + my $rdoc = $nres->get_doc($i); + # display attribte + print "URI: ", $rdoc->attr('@uri'),"\n"; + print "Title: ", $rdoc->attr('@title'),"\n"; + print $rdoc->snippet,"\n"; + } + } else { + die "error: ", $node->status,"\n"; + } =head1 DESCRIPTION @@ -25,6 +82,8 @@ It is implemented as multiple packages which closly resamble Ruby implementation. It also includes methods to manage nodes. +There are few examples in C directory of this distribution. + =cut =head1 Inheritable common methods @@ -41,7 +100,8 @@ =cut sub _s { - my $text = $_[1] || return; + my $text = $_[1]; + return unless defined($text); $text =~ s/\s\s+/ /gs; $text =~ s/^\s+//; $text =~ s/\s+$//; @@ -106,12 +166,12 @@ } elsif ($line =~ m/^$/) { $in_text = 1; next; - } elsif ($line =~ m/^(.+)=(.+)$/) { + } elsif ($line =~ m/^(.+)=(.*)$/) { $self->{attrs}->{ $1 } = $2; next; } - warn "draft ignored: $line\n"; + warn "draft ignored: '$line'\n"; } } @@ -269,7 +329,8 @@ my $draft; foreach my $attr_name (sort keys %{ $self->{attrs} }) { - $draft .= $attr_name . '=' . $self->{attrs}->{$attr_name} . "\n"; + next unless defined(my $v = $self->{attrs}->{$attr_name}); + $draft .= $attr_name . '=' . $v . "\n"; } if ($self->{kwords}) { @@ -317,7 +378,7 @@ package Search::Estraier::Condition; -use Carp qw/confess croak/; +use Carp qw/carp confess croak/; use Search::Estraier; our @ISA = qw/Search::Estraier/; @@ -395,30 +456,71 @@ =head2 set_options - $cond->set_options( SURE => 1 ); + $cond->set_options( 'SURE' ); + + $cond->set_options( qw/AGITO NOIDF SIMPLE/ ); + +Possible options are: + +=over 8 + +=item SURE + +check every N-gram + +=item USUAL + +check every second N-gram + +=item FAST + +check every third N-gram + +=item AGITO + +check every fourth N-gram + +=item NOIDF + +don't perform TF-IDF tuning + +=item SIMPLE + +use simplified query phrase + +=back + +Skipping N-grams will speed up search, but reduce accuracy. Every call to C will reset previous +options; + +This option changed in version C<0.04> of this module. It's backwards compatibile. =cut my $options = { - # check N-gram keys skipping by three SURE => 1 << 0, - # check N-gram keys skipping by two USUAL => 1 << 1, - # without TF-IDF tuning FAST => 1 << 2, - # with the simplified phrase AGITO => 1 << 3, - # check every N-gram key NOIDF => 1 << 4, - # check N-gram keys skipping by one SIMPLE => 1 << 10, }; sub set_options { my $self = shift; - my $option = shift; - confess "unknown option" unless ($options->{$option}); - $self->{options} ||= $options->{$option}; + my $opt = 0; + foreach my $option (@_) { + my $mask; + unless ($mask = $options->{$option}) { + if ($option eq '1') { + next; + } else { + croak "unknown option $option"; + } + } + $opt += $mask; + } + $self->{options} = $opt; } @@ -497,6 +599,35 @@ } +=head2 set_skip + +Set number of skipped documents from beginning of results + + $cond->set_skip(42); + +Similar to C in RDBMS. + +=cut + +sub set_skip { + my $self = shift; + $self->{skip} = shift; +} + +=head2 skip + +Return skip for this condition. + + print $cond->skip; + +=cut + +sub skip { + my $self = shift; + return $self->{skip}; +} + + package Search::Estraier::ResultDocument; use Carp qw/croak/; @@ -640,6 +771,9 @@ print $res->doc_num; +This will return real number of documents (limited by C). +If you want to get total number of hits, see C. + =cut sub doc_num { @@ -671,7 +805,7 @@ Return specific hint from results. - print $rec->hint( 'VERSION' ); + print $res->hint( 'VERSION' ); Possible hints are: C, C, C, C, C, C, C