File Coverage

blib/lib/Elastic/Model/Results.pm
Criterion Covered Total %
statement 15 25 60.0
branch 0 2 0.0
condition 0 8 0.0
subroutine 5 6 83.3
pod 0 1 0.0
total 20 42 47.6


line stmt bran cond sub pod time code
1             package Elastic::Model::Results;
2             $Elastic::Model::Results::VERSION = '0.51';
3 1     1   729 use Carp;
  1         2  
  1         67  
4 1     1   5 use Moose;
  1         1  
  1         7  
5             with 'Elastic::Model::Role::Results';
6 1     1   5341 use MooseX::Types::Moose qw(Num);
  1         2  
  1         8  
7              
8 1     1   3953 use namespace::autoclean;
  1         3  
  1         10  
9              
10             #===================================
11             has 'took' => (
12             #===================================
13                 isa => Num,
14                 is => 'ro',
15                 writer => '_set_took',
16             );
17              
18 1     1   96 no Moose;
  1         2  
  1         5  
19              
20             #===================================
21             sub BUILD {
22             #===================================
23 0     0 0       my $self = shift;
24 0 0             return if $_[0]->{elements};
25              
26 0               my $result = $self->model->search( $self->search );
27              
28 0               my $hits = $result->{hits};
29 0               $self->_set_total( $hits->{total} );
30 0               $self->_set_elements( $hits->{hits} );
31 0   0           $self->_set_max_score( $hits->{max_score} || 0 );
32              
33 0   0           $self->_set_took( $result->{took} || 0 );
34 0   0           $self->_set_facets( $result->{facets} || {} );
35 0   0           $self->_set_aggs( $result->{aggregations} || {} );
36              
37             }
38              
39             1;
40              
41             =pod
42            
43             =encoding UTF-8
44            
45             =head1 NAME
46            
47             Elastic::Model::Results - An iterator over bounded/finite search results
48            
49             =head1 VERSION
50            
51             version 0.51
52            
53             =head1 SYNOPSIS
54            
55             =head2 Retrieve a list of objects
56            
57             Twenty most recently updated active users:
58            
59             $users = $model->view
60             ->index ( 'my_domain' )
61             ->type ( 'user' )
62             ->filterb( 'status' => 'active' )
63             ->sort ( 'timestamp' => 'desc' )
64             ->size ( 20 )
65             ->search
66             ->as_objects;
67            
68             while ( my $user = $users->next ) {
69             say $user->name;
70             }
71            
72             =head2 Retrieve search results
73            
74             Ten most relevant posts for keywords C<perl moose> created since the beginning
75             of 2012, with highlighted snippets, plus the most popular tags:
76            
77             $results = $model->view
78             ->index ( 'my_domain' )
79             ->type ( 'posts' )
80             ->queryb ( 'content' => 'perl moose' )
81             ->filterb ( 'created' => { gt => '2012-01-01' } )
82             ->highlight( 'content' )
83             ->facets ( 'tags' => { terms => { field => 'tags' }} )
84             ->search;
85            
86             printf "Showing %d of %d matching docs\n".
87             $results->size, $results->total;
88            
89             =head2 Highlights
90            
91             while ( my $result = $results->next ) {
92             say "Title:" . $result->object->title;
93             say "Highlights:" .join ', ', $result->highlight('content');
94             }
95            
96             =head2 Aggregations
97            
98             my $tags = $results->agg('tags');
99             my $terms = $tags->{buckets};
100            
101             say "Popular tags: ";
102             for ( @$terms ) {
103             say "$_->{key}: $_->{doc_count}";
104             }
105            
106             =head2 Facets
107            
108             my $tags = $results->facet('tags');
109             my $terms = $tags->{terms};
110            
111             say "Popular tags: ";
112             for ( @$terms ) {
113             say "$_->{term}: $_->{count}";
114             }
115            
116             printf "And $tags->{other} more... ", ;
117            
118             =head1 DESCRIPTION
119            
120             An L<Elastic::Model::Results> object is returned when you call
121             L<Elastic::Model::View/search()>, and is intended for searches that retrieve
122             a maximum of L<size|Elastic::Model::View/size> results in a single request.
123            
124             A C<$results> object can iterate through L<Elastic::Model::Result> objects
125             (with all the result metadata), or just the DocClass object itself
126             (eg C<MyApp::User>). For instance, you can do:
127            
128             $result = $results->next_result;
129             $object = $results->next_object;
130            
131             Or you can set the default type to return:
132            
133             $results->as_objects;
134             $object = $results->next;
135            
136             $results->as_results;
137             $result = $results->next;
138            
139             By default, the short accessors return L<Elastic::Model::Result> objects.
140            
141             Most attributes and accessors in this class come from
142             L<Elastic::Model::Role::Results> and L<Elastic::Model::Role::Iterator>.
143            
144             Also, see L<Elastic::Manual::Searching>.
145            
146             =head1 ATTRIBUTES
147            
148             =head2 took
149            
150             $took = $results->took
151            
152             The number of milliseconds that the request took to run.
153            
154             =head2 size
155            
156             $size = $results->size
157            
158             The number of L</elements> in the C<$results> object;
159            
160             =head2 total
161            
162             $total_matching = $results->total
163            
164             The total number of matching docs found by Elasticsearch. This is
165             distinct from the L</size> which contains the number of results RETURNED
166             by Elasticsearch.
167            
168             =head2 max_score
169            
170             $max_score = $results->max_score
171            
172             The highest score (relevance) found by Elasticsearch. B<Note:> if you
173             are sorting by a field other than C<_score> then you will need
174             to set L<Elastic::Model::View/track_scores> to true to retrieve the
175             L</max_score>.
176            
177             =head2 aggs
178            
179             =head2 agg
180            
181             $aggs = $results->aggs
182             $agg = $results->agg($agg_name)
183            
184             Aggregation results, if any were requested with L<Elastic::Model::View/aggs>.
185            
186             =head2 facets
187            
188             =head2 facet
189            
190             $facets = $results->facets
191             $facet = $results->facet($facet_name)
192            
193             Facet results, if any were requested with L<Elastic::Model::View/facets>.
194            
195             =head2 elements
196            
197             \@elements = $results->elements;
198            
199             An array ref containing all of the data structures that we can iterate over.
200            
201             =head2 search
202            
203             \%search_args = $results->search
204            
205             Contains the hash ref of the search request passed to
206             L<Elastic::Model::Role::Store/search()>
207            
208             =head1 ITERATOR CONTROL
209            
210             =head2 index
211            
212             $index = $results->index; # index of the current element, or undef
213             $results->index(0); # set the current element to the first element
214             $results->index(-1); # set the current element to the last element
215             $results->index(undef); # resets the iterator, no current element
216            
217             L</index> contains the current index of the iterator. Before you start
218             iterating, it will return undef.
219            
220             =head2 reset
221            
222             $results->reset;
223            
224             Resets the iterator so that the next call to L</next> will return
225             the first element. B<Note:> any calls to L</shift> means that those
226             elements have been discarded. L</reset> will not reload these.
227            
228             =head1 INFORMATIONAL ACCESSORS
229            
230             =head2 size
231            
232             $size = $results->size;
233            
234             Returns the number of L</elements>.
235            
236             =head2 even
237            
238             $bool = $results->even
239            
240             Is the current L</index> even?
241            
242             =head2 odd
243            
244             $bool = $results->odd
245            
246             Is the current L</index> odd?
247            
248             =head2 parity
249            
250             $parity = $results->parity
251            
252             Returns C<'odd'> or C<'even'>. Useful for alternating the colour of rows:
253            
254             while ( my $el = $results->next ) {
255             my $css_class = $el->parity;
256             # display row
257             }
258            
259             =head2 is_first
260            
261             $bool = $results->is_first
262            
263             Is the L</current> element the first element?
264            
265             =head2 is_last
266            
267             $bool = $results->is_last
268            
269             Is the L</current> element the last element?
270            
271             =head2 has_next
272            
273             $bool = $results->has_next
274            
275             Is there a L</next> element?
276            
277             =head2 has_prev
278            
279             $bool = $results->has_prev
280            
281             Is there a L</prev> element?
282            
283             =head1 WRAPPERS
284            
285             =head2 as_results()
286            
287             $results = $results->as_results;
288            
289             Sets the "short" accessors (eg L</next>, L</prev>) to return
290             L<Elastic::Model::Result> objects.
291            
292             =head2 as_objects()
293            
294             $objects = $objects->as_objects;
295            
296             Sets the "short" accessors (eg L</next>, L</prev>) to return the object itself,
297             eg C<MyApp::User>
298            
299             =head2 as_elements()
300            
301             $results->as_elements()
302            
303             Sets the "short" accessors (eg L</next>, L</prev>) to return the raw result
304             returned by Elasticsearch.
305            
306             =head2 as_partials()
307            
308             $results->as_partials()
309            
310             Sets the "short" accessors (eg L</next>, L</prev>) to return partial objects
311             as specified by L<Elastic::Model::View/"include_paths / exclude_paths">.
312            
313             =head1 ELEMENT ACCESSORS
314            
315             All of the accessors below have 4 forms:
316            
317             =over
318            
319             =item *
320            
321             Result, eg C<next_result> which returns the full result metadata as an
322             L<Elastic::Model::Result> object.
323            
324             =item *
325            
326             Object, eg C<next_object> which returns the original matching object, eg
327             an instance of C<MyApp::User>
328            
329             =item *
330            
331             Element, eg C<next_element> which returns the raw hashref from Elasticsearch
332            
333             =item *
334            
335             Partial Doc, eg C<next_partial> which returns a partial object as specified
336             by L<Elastic::Model::View/"include_paths / exclude_paths">.
337            
338             =item *
339            
340             Short, which can return any one of the above, depending on which
341             L<Wrapper|/WRAPPERS> is currently in effect.
342            
343             =back
344            
345             Typically you would select the type that you need, then use the short
346             accessors, eg:
347            
348             $results->as_objects;
349            
350             while (my $object = $result->next ) {...}
351            
352             =head2 first
353            
354             $el = $results->first
355            
356             Returns the first element, and resets the iterator so that a call
357             to L</next> will return the second element. If there is
358             no first element, it returns undef.
359            
360             Also C<first_result>, C<first_object>, C<first_element>, C<first_partial>
361            
362             =head2 next
363            
364             $el = $results->next;
365            
366             Returns the next element, and advances the iterator by one. If there is
367             no next element, it returns undef. If the next element is the last
368             element, then it will work like this:
369            
370             $results->next; # returns last element
371             $results->next; # returns undef, and resets iterator
372             $results->next; # returns first element
373            
374             Also C<next_result>, C<next_object>, C<next_element>, C<next_partial>
375            
376             =head2 prev
377            
378             $el = $results->prev
379            
380             Returns the previous element, and moves the iterator one step in reverse. If
381             there is no previous element, it returns undef. If the previous element is the
382             first element, then it will work like this:
383            
384             $results->prev; # returns prev element
385             $results->prev; # returns undef, and resets iterator to end
386             $results->prev; # returns last element
387            
388             Also C<prev_result>, C<prev_object>, C<prev_element>, C<prev_partial>
389            
390             =head2 current
391            
392             $el = $results->current
393            
394             Returns the current element, or undef
395            
396             Also C<current_result>, C<current_object>, C<current_element>, C<current_partial>
397            
398             =head2 last
399            
400             $el = $results->last
401            
402             Returns the last element, and resets the iterator so that a call
403             to L</next> will return undef, and a second call to
404             L</next> will return the first element If there is
405             no last element, it returns undef.
406            
407             Also C<last_result>, C<last_object>, C<last_element>, C<last_partial>
408            
409             =head2 peek_next
410            
411             $el = $results->peek_next
412            
413             Returns the next element (or undef), but doesn't move the iterator.
414            
415             Also C<peek_next_result>, C<peek_next_object>, C<peek_next_element>,
416             C<peek_next_partial>
417            
418             =head2 peek_prev
419            
420             $el = $results->peek_prev
421            
422             Returns the previous element (or undef), but doesn't move the iterator.
423            
424             Also C<peek_prev_result>, C<peek_prev_object>, C<peek_prev_element>,
425             C<peek_prev_partial>
426            
427             =head2 shift
428            
429             $el = $results->shift
430            
431             Returns the L</first> element and removes it from from the list. L</size>
432             will decrease by 1. Returns undef if there are no more elements.
433            
434             Also C<shift_result>, C<shift_object>, C<shift_element>, C<shift_partial>
435            
436             =head2 slice
437            
438             @els = $results->slice($offset,$length);
439            
440             Returns a list of (max) C<$length> elements, starting at C<$offset> (which
441             is zero-based):
442            
443             $results->slice(); # all elements;
444             $results->slice(5); # elements 5..size
445             $results->slice(-5); # elements size-5..size
446             $results->slice(0,10); # elements 0..9
447             $results->slice(5,10); # elements 5..14
448            
449             If your iterator only contains 5 elements:
450            
451             $results->slice(3,10); # elements 3..4
452             $results->slice(10,10); # an empty list
453            
454             Also C<slice_results>, C<slice_objects>, C<slice_elements>, C<slice_partials>
455            
456             =head2 all
457            
458             @els = $results->all
459            
460             Returns all L</elements> as a list.
461            
462             Also C<all_results>, C<all_objects>, C<all_elements>, C<all_partials>
463            
464             =head1 AUTHOR
465            
466             Clinton Gormley <drtech@cpan.org>
467            
468             =head1 COPYRIGHT AND LICENSE
469            
470             This software is copyright (c) 2015 by Clinton Gormley.
471            
472             This is free software; you can redistribute it and/or modify it under
473             the same terms as the Perl 5 programming language system itself.
474            
475             =cut
476              
477             __END__
478            
479             # ABSTRACT: An iterator over bounded/finite search results
480            
481