blob: 726fa1c0a2b085b4abb66f69e139b2cd044f1bf6 [file] [log] [blame]
package Krawfish::Result::Sort::Filter;
use parent 'Krawfish::Corpus';
use Krawfish::Log;
use strict;
use warnings;
use constant DEBUG => 0;
# This is a corpus query implementation
#
# TODO: Better move to Krawfish::Corpus
sub new {
my $class = shift;
my %param = @_;
my $ranking = $param{index}->fields->ranked_by($param{field});
my $max = $ranking->max if $param{desc};
bless {
query => $param{query},
max_rank_ref => $param{max_rank_ref},
field => $param{field},
desc => $param{desc},
ranking => $ranking,
max => $max,
init => 0
}, $class;
};
# Forward to next document
sub next {
my $self = shift;
my $query = $self->{query};
# Get next document
while ($query->next) {
# Check object
return 1 if $self->_check;
};
# No next
return;
};
# Check the document id for the rank
sub _check {
my $self = shift;
# Maximum rank reference
my $max_rank_ref = $self->{max_rank_ref};
# Get the current doc_id
my $query = $self->{query};
my $current = $query->current;
my $doc_id = $current->doc_id;
# Get rank for field
my $rank = $self->{ranking}->get($doc_id);
# Invert rank if descending field is required
$rank = $self->{max} - $rank if $self->{max};
if (DEBUG) {
print_log('vc_sort_filter', 'Current posting is ' . $current->to_string);
};
# Rank is smaller then required
if ($rank <= $$max_rank_ref) {
# Document is fine
$self->{current} = $current;
return 1;
};
if (DEBUG) {
print_log('vc_sort_filter', $current->to_string . ' is filtered out');
};
$self->{current} = undef;
return;
};
# Get current document
sub current {
$_[0]->{current};
};
# Skip to the relevant document
sub skip_doc {
my ($self, $doc_id) = @_;
my $query = $self->{query};
# Skip the document
if ($query->skip_doc($doc_id)) {
# Return the document id, if it matches
return $doc_id if $query->_check;
# Get the next matching element
if ($self->next) {
# return the document id
return $self->{current}->doc_id;
};
};
# Fail
return;
};
1;