File Coverage

blib/lib/Elastic/Model/Role/Results.pm
Criterion Covered Total %
statement 15 105 14.2
branch 0 10 0.0
condition 0 12 0.0
subroutine 5 51 9.8
pod 33 33 100.0
total 53 211 25.1


line stmt bran cond sub pod time code
1             package Elastic::Model::Role::Results;
2             $Elastic::Model::Role::Results::VERSION = '0.51';
3 1     1   646 use Carp;
  1         2  
  1         64  
4 1     1   4 use Moose::Role;
  1         1  
  1         7  
5              
6             with 'Elastic::Model::Role::Iterator';
7              
8 1     1   4122 use MooseX::Types::Moose qw(HashRef Int Num CodeRef Bool);
  1         2  
  1         9  
9 1     1   4622 use namespace::autoclean;
  1         2  
  1         9  
10              
11             #===================================
12             has 'search' => (
13             #===================================
14                 isa => HashRef,
15                 is => 'ro',
16                 required => 1,
17             );
18              
19             #===================================
20             has 'total' => (
21             #===================================
22                 isa => Int,
23                 is => 'ro',
24                 writer => '_set_total',
25             );
26              
27             #===================================
28             has 'max_score' => (
29             #===================================
30                 isa => Num,
31                 is => 'ro',
32                 writer => '_set_max_score',
33             );
34              
35             #===================================
36             has 'facets' => (
37             #===================================
38                 isa => HashRef,
39                 traits => ['Hash'],
40                 is => 'ro',
41                 writer => '_set_facets',
42                 handles => { facet => 'get' }
43             );
44              
45             #===================================
46             has 'aggs' => (
47             #===================================
48                 isa => HashRef,
49                 traits => ['Hash'],
50                 is => 'ro',
51                 writer => '_set_aggs',
52                 handles => { agg => 'get' }
53             );
54              
55             #===================================
56             has 'is_partial' => (
57             #===================================
58                 isa => Bool,
59                 is => 'ro',
60                 lazy => 1,
61                 builder => '_build_is_partial',
62             );
63              
64             #===================================
65             has '_as_result' => (
66             #===================================
67                 isa => CodeRef,
68                 is => 'ro',
69                 lazy => 1,
70                 builder => '_as_result_builder'
71             );
72              
73             #===================================
74             has '_as_results' => (
75             #===================================
76                 isa => CodeRef,
77                 is => 'ro',
78                 lazy => 1,
79                 builder => '_as_results_builder'
80             );
81              
82             #===================================
83             has '_as_object' => (
84             #===================================
85                 isa => CodeRef,
86                 is => 'ro',
87                 lazy => 1,
88                 builder => '_as_object_builder'
89             );
90              
91             #===================================
92             has '_as_objects' => (
93             #===================================
94                 isa => CodeRef,
95                 is => 'ro',
96                 lazy => 1,
97                 builder => '_as_objects_builder'
98             );
99              
100             #===================================
101             has '_as_partial' => (
102             #===================================
103                 isa => CodeRef,
104                 is => 'ro',
105                 lazy => 1,
106                 builder => '_as_partial_builder'
107             );
108              
109             #===================================
110             has '_as_partials' => (
111             #===================================
112                 isa => CodeRef,
113                 is => 'ro',
114                 lazy => 1,
115                 builder => '_as_partials_builder'
116             );
117              
118 1     1   238 no Moose;
  1         2  
  1         6  
119              
120             #===================================
121             sub _build_is_partial {
122             #===================================
123 0     0         my $self = shift;
124 0               return exists $self->search->{_source};
125             }
126              
127             #===================================
128             sub _as_result_builder {
129             #===================================
130 0     0         my $self = shift;
131 0               my $result_class = $self->model->result_class;
132 0               my $is_partial = $self->is_partial;
133                 sub {
134 0 0   0             $_[0]
135                         && $result_class->new(
136                         result => $_[0],
137                         is_partial => $is_partial
138                         );
139                     }
140 0           }
141              
142             #===================================
143             sub _as_results_builder {
144             #===================================
145 0     0         my $self = shift;
146 0               my $result_class = $self->model->result_class;
147 0               my $is_partial = $self->is_partial;
148                 sub {
149 0     0             map { $result_class->new( result => $_, is_partial => $is_partial ) }
  0            
150                         @_;
151 0               };
152             }
153              
154             #===================================
155             sub _as_object_builder {
156             #===================================
157 0     0         my $self = shift;
158 0               my $model = $self->model;
159 0               my $is_partial = $self->is_partial;
160                 sub {
161 0 0   0             my $raw = shift or return;
162 0   0               $raw->{_object} ||= do {
163 0                       my $uid = Elastic::Model::UID->new_from_store($raw);
164 0 0                     my $source = $is_partial ? undef : $raw->{_source};
165 0                       $model->get_doc( uid => $uid, source => $source );
166                     };
167 0               };
168             }
169              
170             #===================================
171             sub _as_objects_builder {
172             #===================================
173 0     0         my $self = shift;
174 0               my $m = $self->model;
175 0               my $is_partial = $self->is_partial;
176                 sub {
177                     map {
178 0   0 0                 $_->{_object} ||= do {
  0            
179 0                           my $uid = Elastic::Model::UID->new_from_store($_);
180 0 0                         my $source = $is_partial ? undef : $_->{_source};
181 0                           $m->get_doc( uid => $uid, source => $source );
182                         };
183                     } @_;
184 0               };
185             }
186              
187             #===================================
188             sub _as_partial_builder {
189             #===================================
190 0     0         my $self = shift;
191 0               my $model = $self->model;
192                 sub {
193 0 0   0             my $raw = shift or return;
194 0   0               $raw->{_partial} ||= do {
195 0                       my $uid = Elastic::Model::UID->new_partial($raw);
196 0                       $model->new_partial_doc(
197                             uid => $uid,
198                             partial_source => $raw->{_source}
199                         );
200                         }
201              
202 0               };
203             }
204              
205             #===================================
206             sub _as_partials_builder {
207             #===================================
208 0     0         my $self = shift;
209 0               my $m = $self->model;
210                 sub {
211                     map {
212 0   0 0                 $_->{_partial} ||= do {
  0            
213 0                           my $uid = Elastic::Model::UID->new_partial($_);
214 0                           $m->new_partial_doc(
215                                 uid => $uid,
216                                 partial_source => $_->{_source}
217                             );
218                             }
219                     } @_;
220 0               };
221             }
222              
223             #===================================
224             sub as_results {
225             #===================================
226 0     0 1       my $self = shift;
227 0               $self->wrapper( $self->_as_result );
228 0               $self->multi_wrapper( $self->_as_results );
229 0               $self;
230             }
231              
232             #===================================
233             sub as_objects {
234             #===================================
235 0     0 1       my $self = shift;
236 0               $self->wrapper( $self->_as_object );
237 0               $self->multi_wrapper( $self->_as_objects );
238 0               $self;
239             }
240              
241             #===================================
242             sub as_partials {
243             #===================================
244 0     0 1       my $self = shift;
245 0               $self->wrapper( $self->_as_partial );
246 0               $self->multi_wrapper( $self->_as_partials );
247 0               $self;
248             }
249              
250             #===================================
251 0     0 1   sub first_result { $_[0]->_as_result->( $_[0]->first_element ) }
252 0     0 1   sub last_result { $_[0]->_as_result->( $_[0]->last_element ) }
253 0     0 1   sub next_result { $_[0]->_as_result->( $_[0]->next_element ) }
254 0     0 1   sub prev_result { $_[0]->_as_result->( $_[0]->prev_element ) }
255 0     0 1   sub current_result { $_[0]->_as_result->( $_[0]->current_element ) }
256 0     0 1   sub peek_next_result { $_[0]->_as_result->( $_[0]->peek_next_element ) }
257 0     0 1   sub peek_prev_result { $_[0]->_as_result->( $_[0]->peek_prev_element ) }
258 0     0 1   sub shift_result { $_[0]->_as_result->( $_[0]->shift_element ) }
259 0     0 1   sub all_results { $_[0]->_as_results->( $_[0]->all_elements ) }
260             #===================================
261              
262             #===================================
263             sub slice_results {
264             #===================================
265 0     0 1       my $self = shift;
266 0               $self->_as_results->( $self->slice_elements(@_) );
267             }
268              
269             #===================================
270 0     0 1   sub first_object { $_[0]->_as_object->( $_[0]->first_element ) }
271 0     0 1   sub last_object { $_[0]->_as_object->( $_[0]->last_element ) }
272 0     0 1   sub next_object { $_[0]->_as_object->( $_[0]->next_element ) }
273 0     0 1   sub prev_object { $_[0]->_as_object->( $_[0]->prev_element ) }
274 0     0 1   sub current_object { $_[0]->_as_object->( $_[0]->current_element ) }
275 0     0 1   sub peek_next_object { $_[0]->_as_object->( $_[0]->peek_next_element ) }
276 0     0 1   sub peek_prev_object { $_[0]->_as_object->( $_[0]->peek_prev_element ) }
277 0     0 1   sub shift_object { $_[0]->_as_object->( $_[0]->shift_element ) }
278 0     0 1   sub all_objects { $_[0]->_as_objects->( $_[0]->all_elements ) }
279             #===================================
280              
281             #===================================
282             sub slice_objects {
283             #===================================
284 0     0 1       my $self = shift;
285 0               $self->_as_objects->( $self->slice_elements(@_) );
286             }
287              
288             #===================================
289 0     0 1   sub first_partial { $_[0]->_as_partial->( $_[0]->first_element ) }
290 0     0 1   sub last_partial { $_[0]->_as_partial->( $_[0]->last_element ) }
291 0     0 1   sub next_partial { $_[0]->_as_partial->( $_[0]->next_element ) }
292 0     0 1   sub prev_partial { $_[0]->_as_partial->( $_[0]->prev_element ) }
293 0     0 1   sub current_partial { $_[0]->_as_partial->( $_[0]->current_element ) }
294 0     0 1   sub peek_next_partial { $_[0]->_as_partial->( $_[0]->peek_next_element ) }
295 0     0 1   sub peek_prev_partial { $_[0]->_as_partial->( $_[0]->peek_prev_element ) }
296 0     0 1   sub shift_partial { $_[0]->_as_partial->( $_[0]->shift_element ) }
297 0     0 1   sub all_partials { $_[0]->_as_partials->( $_[0]->all_elements ) }
298             #===================================
299              
300             #===================================
301             sub slice_partials {
302             #===================================
303 0     0 1       my $self = shift;
304 0               $self->_as_partials->( $self->slice_elements(@_) );
305             }
306              
307             1;
308              
309             =pod
310            
311             =encoding UTF-8
312            
313             =head1 NAME
314            
315             Elastic::Model::Role::Results - An iterator role for search results
316            
317             =head1 VERSION
318            
319             version 0.51
320            
321             =head1 DESCRIPTION
322            
323             L<Elastic::Model::Role::Results> adds a number of methods and attributes
324             to those provided by L<Elastic::Model::Role::Iterator> to better handle
325             result sets from Elasticsearch. It is used by L<Elastic::Model::Results>,
326             L<Elastic::Model::Results::Cached> and by L<Elastic::Model::Results::Scrolled>.
327            
328             See those modules for more complete documentation. This module just
329             documents the attributes and methods added in L<Elastic::Model::Role::Results>
330            
331             =head1 ATTRIBUTES
332            
333             =head2 size
334            
335             $size = $results->size
336            
337             The number of L</elements> in the C<$results> object;
338            
339             =head2 total
340            
341             $total_matching = $results->total
342            
343             The total number of matching docs found by Elasticsearch. This is
344             distinct from the L</size> which contains the number of results RETURNED
345             by Elasticsearch.
346            
347             =head2 max_score
348            
349             $max_score = $results->max_score
350            
351             The highest score (relevance) found by Elasticsearch. B<Note:> if you
352             are sorting by a field other than C<_score> then you will need
353             to set L<Elastic::Model::View/track_scores> to true to retrieve the
354             L</max_score>.
355            
356             =head2 aggs
357            
358             =head2 agg
359            
360             $aggs = $results->aggs
361             $agg = $results->agg($agg_name)
362            
363             Aggregation results, if any were requested with L<Elastic::Model::View/aggs>.
364            
365             =head2 facets
366            
367             =head2 facet
368            
369             $facets = $results->facets
370             $facet = $results->facet($facet_name)
371            
372             Facet results, if any were requested with L<Elastic::Model::View/facets>.
373            
374             =head2 elements
375            
376             \@elements = $results->elements;
377            
378             An array ref containing all of the data structures that we can iterate over.
379            
380             =head2 search
381            
382             \%search_args = $results->search
383            
384             Contains the hash ref of the search request passed to
385             L<Elastic::Model::Role::Store/search()>
386            
387             =head2 is_partial
388            
389             $bool = $result->is_partial
390            
391             Returns C<true> or C<false> to indicate whether the specified search
392             returns full or partial results.
393            
394             =head1 WRAPPERS
395            
396             =head2 as_results()
397            
398             $results = $results->as_results;
399            
400             Sets the "short" accessors (eg L<Elastic::Model::Role::Iterator/next> or
401             L<Elastic::Model::Role::Iterator/prev>) to return
402             L<Elastic::Model::Result> objects.
403            
404             =head2 as_objects()
405            
406             $objects = $objects->as_objects;
407            
408             Sets the "short" accessors (eg L<Elastic::Model::Role::Iterator/next> or
409             L<Elastic::Model::Role::Iterator/prev>) to return the object itself,
410             eg C<MyApp::User>
411            
412             =head2 as_partials()
413            
414             $results->as_partials()
415            
416             Sets the "short" accessors (eg L<Elastic::Model::Role::Iterator/next> or
417             L<Elastic::Model::Role::Iterator/prev>) to return partial objects
418             as specified by L<Elastic::Model::View/"include_paths / exclude_paths">.
419            
420             =head1 RESULT ACCESSORS
421            
422             Each of the methods listed below takes the result of the related
423             C<_element> accessor in L<Elastic::Model::Role::Iterator> and wrap it
424             in an L<Elastic::Model::Result> object. For instance:
425            
426             $result = $results->next_result;
427            
428             =head2 first_result
429            
430             =head2 last_result
431            
432             =head2 next_result
433            
434             =head2 prev_result
435            
436             =head2 current_result
437            
438             =head2 peek_next_result
439            
440             =head2 peek_prev_result
441            
442             =head2 shift_result
443            
444             =head2 all_results
445            
446             =head2 slice_results
447            
448             =head1 OBJECT ACCESSORS
449            
450             Each of the methods listed below takes the result of the related
451             C<_element> accessor in L<Elastic::Model::Role::Iterator> and inflates the
452             related object (eg a C<MyApp::User> object). For instance:
453            
454             $object = $results->next_object;
455            
456             =head2 first_object
457            
458             =head2 last_object
459            
460             =head2 next_object
461            
462             =head2 prev_object
463            
464             =head2 current_object
465            
466             =head2 peek_next_object
467            
468             =head2 peek_prev_object
469            
470             =head2 shift_object
471            
472             =head2 all_objects
473            
474             =head2 slice_objects
475            
476             =head1 PARTIAL OBJECT ACCESSORS
477            
478             Each of the methods listed below takes the result of the related
479             C<_element> accessor in L<Elastic::Model::Role::Iterator> and inflates the
480             related partial object as specified by
481             L<Elastic::Model::View/"include_paths / exclude_paths">. For instance:
482            
483             $object = $results->next_partial;
484            
485             =head2 first_partial
486            
487             =head2 last_partial
488            
489             =head2 next_partial
490            
491             =head2 prev_partial
492            
493             =head2 current_partial
494            
495             =head2 peek_next_partial
496            
497             =head2 peek_prev_partial
498            
499             =head2 shift_partial
500            
501             =head2 all_partials
502            
503             =head2 slice_partials
504            
505             =head1 AUTHOR
506            
507             Clinton Gormley <drtech@cpan.org>
508            
509             =head1 COPYRIGHT AND LICENSE
510            
511             This software is copyright (c) 2015 by Clinton Gormley.
512            
513             This is free software; you can redistribute it and/or modify it under
514             the same terms as the Perl 5 programming language system itself.
515            
516             =cut
517              
518             __END__
519            
520             # ABSTRACT: An iterator role for search results
521            
522