| Akron | 5cf5fca | 2017-10-09 19:01:47 +0200 | [diff] [blame] | 1 | package Krawfish::Compile::Segment::Sort::Field; |
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 2 | use Krawfish::Log; |
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 3 | use strict; |
| 4 | use warnings; | ||||
| 5 | |||||
| Akron | 5cf5fca | 2017-10-09 19:01:47 +0200 | [diff] [blame] | 6 | use constant DEBUG => 0; |
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 7 | |
| 8 | # TODO: | ||||
| 9 | # Use this an instantiate it directly with | ||||
| 10 | # a ranking! | ||||
| 11 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 12 | # Sorting criterion for field ranks. |
| 13 | |||||
| 14 | # TODO: | ||||
| 15 | # Probably not only support ranks but all kinds of sorting | ||||
| 16 | # by having a get_lt() API that also works for strings! | ||||
| 17 | |||||
| Akron | 96c2f14 | 2017-09-28 13:13:15 +0200 | [diff] [blame] | 18 | # TODO: |
| 19 | # Return max rank for unknown fields! | ||||
| 20 | |||||
| Akron | d5abf65 | 2017-11-22 15:47:41 +0100 | [diff] [blame^] | 21 | # TODO: |
| 22 | # This may need to be an inflatable | ||||
| 23 | |||||
| 24 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 25 | sub new { |
| 26 | my $class = shift; | ||||
| 27 | |||||
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 28 | my ($segment, $field_id, $descending) = @_; |
| 29 | |||||
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 30 | # Get ranking |
| 31 | my $rank = $segment->field_ranks->by($field_id); | ||||
| 32 | |||||
| 33 | return unless $rank; | ||||
| 34 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 35 | my $self = bless { |
| Akron | 96c2f14 | 2017-09-28 13:13:15 +0200 | [diff] [blame] | 36 | field_id => $field_id, |
| 37 | desc => $descending, | ||||
| 38 | max_rank => $rank->max_rank | ||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 39 | }, $class; |
| 40 | |||||
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 41 | # Get fields in descending order |
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 42 | if ($descending) { |
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 43 | |
| 44 | # This may be a real descending order file | ||||
| 45 | # or a reversed single-valued ascending order file | ||||
| Akron | 96c2f14 | 2017-09-28 13:13:15 +0200 | [diff] [blame] | 46 | $self->{rank} = $rank->descending or return; |
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 47 | } |
| 48 | |||||
| 49 | # Get fields in ascending order | ||||
| 50 | else { | ||||
| Akron | 96c2f14 | 2017-09-28 13:13:15 +0200 | [diff] [blame] | 51 | $self->{rank} = $rank->ascending or return; |
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 52 | }; |
| 53 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 54 | return $self; |
| 55 | }; | ||||
| 56 | |||||
| Akron | 4204f17 | 2017-10-02 22:32:02 +0200 | [diff] [blame] | 57 | sub type { |
| 58 | 'field'; | ||||
| 59 | }; | ||||
| 60 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 61 | |
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 62 | # Get the rank for this criterion |
| 63 | sub rank_for { | ||||
| 64 | my ($self, $doc_id) = @_; | ||||
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 65 | |
| Akron | d5abf65 | 2017-11-22 15:47:41 +0100 | [diff] [blame^] | 66 | return $self->{rank}->rank_for($doc_id) || ($self->max_rank + 1); |
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 67 | |
| 68 | # Get rank if rank is littler than value | ||||
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 69 | # my $value = shift; |
| 70 | # return $self->{rank}->rank_doc_lt($doc_id, $value); | ||||
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 71 | # my $max = $ranking->max if $desc; |
| Akron | 8d0593b | 2017-08-28 19:35:55 +0200 | [diff] [blame] | 72 | }; |
| 73 | |||||
| 74 | |||||
| 75 | sub criterion { | ||||
| 76 | $_[0]->{field_id}; | ||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 77 | }; |
| 78 | |||||
| Akron | 96c2f14 | 2017-09-28 13:13:15 +0200 | [diff] [blame] | 79 | sub max_rank { |
| 80 | $_[0]->{max_rank} | ||||
| 81 | } | ||||
| 82 | |||||
| 83 | sub term_id { | ||||
| 84 | $_[0]->{field_id}; | ||||
| 85 | }; | ||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 86 | |
| Akron | d5abf65 | 2017-11-22 15:47:41 +0100 | [diff] [blame^] | 87 | |
| 88 | # Stringification | ||||
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 89 | sub to_string { |
| 90 | my $self = shift; | ||||
| Akron | d5abf65 | 2017-11-22 15:47:41 +0100 | [diff] [blame^] | 91 | return 'field=#' . $self->{field_id} . ($self->{desc} ? '>' : '<') |
| Akron | 510baba | 2017-09-27 19:14:48 +0200 | [diff] [blame] | 92 | }; |
| 93 | |||||
| Akron | fb9e652 | 2017-05-27 14:35:00 +0200 | [diff] [blame] | 94 | 1; |