KSx-Search-WildCardQuery
view release on metacpan or search on metacpan
lib/KSx/Search/RegexpTermQuery.pm view on Meta::CPAN
my $plist = $post_reader->posting_list(
term => $term,
field => $field{$parent},
);
my $posting; my $weight;
while (my $doc_num = $plist ->next) {
# For efficiencyâs sake, weâll collect the results now, to
# avoid iterating through postings (the slowest part of search-
# ing) more than once, even though this code probably belongs
# in RegexpTermScorer
my $posting ||= $plist->get_posting;
$hits{$doc_num} +=
$weight ||= $posting->get_freq * $posting->get_weight
}
} continue {
last unless $lexcn->next ;
}
my $doc_freq = scalar keys %hits;
# Save the hits and terms for later
# $plists{$self} = \@plists;
$tfs{$self} = \%hits;
$terms{$self} = \@terms;
# Calculate and store the IDF
my $max_doc = $searcher->doc_max;
my $idf = $idf{$self} = $max_doc
? 1 + log( $max_doc / ( 1 + $doc_freq ) )
: 1
;
$raw_impact{$self} = $idf * $parent->get_boost;
# make final preparations
$self->perform_query_normalization($searcher);
$self;
}
sub perform_query_normalization {
# copied from KinoSearch::Search::Weight originally
my ( $self, $searcher ) = @_;
my $sim = $self->get_similarity;
my $factor = $self->sum_of_squared_weights; # factor = ( tf_q * idf_t )
$factor = $sim->query_norm($factor); # factor /= norm_q
$self->normalize($factor); # impact *= factor
}
sub get_value { shift->get_parent->get_boost }
sub sum_of_squared_weights { $raw_impact{+shift}**2 }
sub normalize { # copied from TermQuery
my ( $self, $query_norm_factor ) = @_;
$query_norm_factor{$self} = $query_norm_factor;
# Multiply raw impact by ( tf_q * idf_q / norm_q )
#
# Note: factoring in IDF a second time is correct. See formula.
$normalized_impact{$self}
= $raw_impact{$self} * $idf{$self} * $query_norm_factor;
}
sub make_matcher {
my $self = shift;
return KSx::Search::RegexpTermScorer->new(
# posting_lists => $plists{$self},
@_,
compiler => $self,
);
}
sub highlight_spans { # plagiarised form of TermWeightâs routine
my ($self, %args) = @_;
my $doc_vector = $args{doc_vec};
my $field_name = $args{field};
return if $field{$self->get_parent} ne $field_name;
my $searcher = $args{searcher};
my $terms = $terms{$self};
require KinoSearch::Search::Span;
my @posits;
my $weight_val = $self->get_value;
for (@$terms) {
my $term_vector
= $doc_vector->term_vector( field => $field_name, term => $_ );
next unless defined $term_vector;
my $starts = $term_vector->get_start_offsets->to_arrayref;
my $ends = $term_vector->get_end_offsets->to_arrayref;
while (@$starts) {
my $start = shift @$starts;
push @posits, KinoSearch::Search::Span->new(
offset => $start,
length => shift(@$ends)-$start,
weight => $weight_val,
);
}
}
return \@posits;
}
package KSx::Search::RegexpTermScorer;
use base 'KinoSearch::Search::Matcher';
use Hash::Util::FieldHash::Compat 'fieldhashes';
fieldhashes\my( %doc_nums, %pos, %wv, %sim, %compiler );
sub new {
my ($class, %args) = @_;
# my $plists = delete $args{posting_lists};
my $compiler = delete $args{compiler};
my $reader = delete $args{reader};
my $need_score = delete $args{need_score};
my $self = $class->SUPER::new(%args);
$sim{$self} = $compiler->get_similarity;
( run in 1.493 second using v1.01-cache-2.11-cpan-870870ed90f )