blob: dce5624897b1b2dd4c7174a5a2812207260fad32 [file] [log] [blame]
package Krawfish::Compile::Node::Aggregate;
use strict;
use warnings;
use Role::Tiny;
with 'Krawfish::Compile::Node';
# TODO:
# Implement the aggregate() method on all Node::Aggregate::*
# May be renamed to
# - Krawfish::MultiSegment::Aggregate
# - Krawfish::MultiNodes::Aggregate
# To aggregate top_k matches from multiple segments,
# fetch all top segments and put them in a
# priority queue. Get top match, and request the next
# match from that segment.
# Do this, until k is fine.
# Distributed results are returned from each index
# in an aggregate data section followed by result lines.
# The result lines can be returned using next_current() etc.
# while the data aggregation section is returned by the first
# call.
sub new {
my $class = shift;
bless {
query => shift,
aggregates => shift,
_fetched => undef,
_result => undef
}, $class;
};
# This will read all header information from the nodes
# and aggregate the date
sub process_head {
my ($self, $head) = @_;
# Get aggregation data from head
my $data = $head->{aggregate};
# Iterate over all registered aggregates
foreach (@{$self->{aggregates}}) {
# Aggregate head data
$_->aggregate($data);
};
# Go deeper
$self->{query}->process_head($head);
};
# Get result information
# Maybe "on final"
sub result {
my $self = shift;
# Fetch all aggregation data from the types
my $result = {};
# Add to result hash
foreach my $op (@{$self->{aggregates}}) {
$result->{$op->type} = $op->aggregate;
};
};
# Next query line - do nothing
sub next {
$_[0]->{query}->next;
};
sub to_string {
my $self = shift;
return 'aggr(' .
join(',', map { $_->to_string } @{$self->{aggregates}}) .
':' . $self->{query}->to_string . ')';
};
1;