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 )