File Coverage

blib/lib/WebService/Algolia.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package WebService::Algolia;
2             $WebService::Algolia::VERSION = '0.1002';
3 5     5   243391 use 5.008001;
  5         12  
  5         150  
4 5     5   2411 use Moo;
  5         45949  
  5         36  
5             with 'WebService::Client';
6              
7             # VERSION
8              
9 5     5   5928 use Carp;
  5         7  
  5         274  
10 5     5   4057 use Method::Signatures;
  0            
  0            
11             use Storable qw(dclone);
12             use URI;
13              
14             has api_key => ( is => 'ro', required => 1 );
15             has application_id => ( is => 'ro', required => 1 );
16             has batch_mode => ( is => 'rw', default => 0, init_arg => undef );
17              
18             has '+base_url' => ( is => 'ro', default =>
19             method {
20             'https://' . $self->application_id . '.algolia.io/1'
21             }
22             );
23              
24             method BUILD(...) {
25             $self->ua->default_header('X-Algolia-Application-Id' => $self->application_id);
26             $self->ua->default_header('X-Algolia-API-Key' => $self->api_key);
27             }
28              
29             method get_indexes {
30             return $self->get('/indexes');
31             }
32              
33             method browse_index(Str $index) {
34             return $self->get("/indexes/$index/browse");
35             }
36              
37             method query_index(HashRef $query) {
38             my $index = delete $query->{index};
39             croak 'The \'index\' parameter is required' unless $index;
40             return $self->get("/indexes/$index", $query);
41             }
42              
43             method query_indexes(ArrayRef $queries) {
44             my $requests = dclone $queries;
45             $requests = [ map {
46             my $index = delete $_->{index};
47             croak 'The \'index\' parameter is required' unless $index;
48             my $uri = URI->new;
49             $uri->query_form( %$_ );
50             { indexName => $index, params => substr($uri, 1) };
51             } @$requests ];
52             return $self->post('/indexes/*/queries', { requests => $requests });
53             }
54              
55             method clear_index(Str $index) {
56             return $self->post("/indexes/$index/clear", {});
57             }
58              
59             method copy_index(Str $source, Str $destination) {
60             return $self->post("/indexes/$source/operation", {
61             operation => 'copy',
62             destination => $destination,
63             });
64             }
65              
66             method move_index(Str $source, Str $destination) {
67             return $self->post("/indexes/$source/operation", {
68             operation => 'move',
69             destination => $destination,
70             });
71             }
72              
73             method delete_index(Str $index) {
74             return $self->delete("/indexes/$index");
75             }
76              
77             method get_index_settings(Str $index) {
78             return $self->get("/indexes/$index/settings");
79             }
80              
81             method update_index_settings(Str $index, $settings) {
82             return $self->put("/indexes/$index/settings", $settings);
83             }
84              
85             method get_index_object(Str $index, Str $object_id) {
86             return $self->get("/indexes/$index/$object_id");
87             }
88              
89             method get_index_objects(ArrayRef $objects) {
90             my $requests = dclone $objects;
91             $requests = [ map {
92             my $index = delete $_->{index};
93             croak 'The \'index\' parameter is required' unless $index;
94             my $object = delete $_->{object};
95             croak 'The \'object\' parameter is required' unless $object;
96             { indexName => $index, objectID => $object }
97             } @$requests ];
98             return $self->post('/indexes/*/objects', { requests => $requests });
99             }
100              
101             method create_index_object(Str $index, HashRef $data) {
102             return $self->post("/indexes/$index", $data);
103             }
104              
105             method replace_index_object(Str $index, Str $object_id, HashRef $data) {
106             return $self->put("/indexes/$index/$object_id", $data);
107             }
108              
109             method update_index_object(Str $index, Str $object_id, HashRef $data) {
110             return $self->post("/indexes/$index/$object_id/partial", $data);
111             }
112              
113             method delete_index_object(Str $index, Str $object_id) {
114             return $self->delete("/indexes/$index/$object_id");
115             }
116              
117             method batch_index_objects(Str $index, ArrayRef[CodeRef] $operations) {
118             $self->batch_mode(1);
119             my $requests = [ map { $_->() } @$operations ];
120             $self->batch_mode(0);
121             return $self->post("/indexes/$index/batch", { requests => $requests });
122             }
123              
124             method get_index_keys(Str $index = '') {
125             return $index
126             ? $self->get("/indexes/$index/keys")
127             : $self->get('/indexes/*/keys');
128             }
129              
130             method get_index_key(Str $index, Str $key) {
131             return $self->get("/indexes/$index/keys/$key");
132             }
133              
134             method create_index_key(Str $index, HashRef $data) {
135             return $self->post("/indexes/$index/keys", $data);
136             }
137              
138             method update_index_key(Str $index, Str $key, HashRef $data) {
139             return $self->put("/indexes/$index/keys/$key", $data);
140             }
141              
142             method delete_index_key(Str $index, Str $key) {
143             return $self->delete("/indexes/$index/keys/$key");
144             }
145              
146             method get_task_status(Str $index, Str $task_id) {
147             return $self->get("/indexes/$index/task/$task_id");
148             }
149              
150             method get_keys {
151             return $self->get('/keys');
152             }
153              
154             method get_key(Str $key) {
155             return $self->get("/keys/$key");
156             }
157              
158             method create_key(HashRef $data) {
159             return $self->post('/keys', $data);
160             }
161              
162             method update_key(Str $key, HashRef $data) {
163             return $self->put("/keys/$key", $data);
164             }
165              
166             method delete_key(Str $key) {
167             return $self->delete("/keys/$key");
168             }
169              
170             method get_logs(HashRef $params = {}) {
171             return $self->get('/logs', $params);
172             }
173              
174             method get_popular_searches(ArrayRef[Str] $indexes = []) {
175             my $csv_indexes = join ',', @$indexes;
176             return $self->get(_analytics_uri("/searches/$csv_indexes/popular"));
177             }
178              
179             method get_unpopular_searches(ArrayRef[Str] $indexes = []) {
180             my $csv_indexes = join ',', @$indexes;
181             return $self->get(_analytics_uri("/searches/$csv_indexes/noresults"));
182             }
183              
184             func _analytics_uri(Str $uri) {
185             return "https://analytics.algolia.com/1$uri";
186             }
187              
188             for my $func (qw/put post delete/) {
189             around $func => sub {
190             my ($orig, $self, @args) = @_;
191             if ($self->batch_mode) {
192             my ($path, $body) = @args;
193             return {
194             method => uc $func,
195             path => "/1$path",
196             (body => $body) x!! $body,
197             };
198             } else {
199             return $self->$orig(@args);
200             }
201             };
202             }
203              
204             # ABSTRACT: Algolia API Bindings
205              
206              
207             1;
208              
209             __END__
210              
211             =pod
212              
213             =encoding UTF-8
214              
215             =head1 NAME
216              
217             WebService::Algolia - Algolia API Bindings
218              
219             =head1 VERSION
220              
221             version 0.1002
222              
223             =head1 SYNOPSIS
224              
225             use WebService::Algolia;
226              
227             my $alg = WebService::Algolia->new(
228             application_id => '12345',
229             api_key => 'abcde',
230             );
231              
232             $alg->get_indexes;
233              
234             =head1 DESCRIPTION
235              
236             This module provides bindings for the
237             L<Algolia|https://www.algolia.com/doc> API.
238              
239             =for markdown [![Build Status](https://travis-ci.org/aanari/WebService-Algolia.svg?branch=master)](https://travis-ci.org/aanari/WebService-Algolia)
240              
241             =head1 METHODS
242              
243             =head2 new
244              
245             Instantiates a new WebService::Algolia client object.
246              
247             my $alg = WebService::Algolia->new(
248             application_id => $application_id,
249             api_key => $api_key,
250             timeout => $retries, # optional
251             retries => $retries, # optional
252             );
253              
254             B<Parameters>
255              
256             =over 4
257              
258             =item - C<application_id>
259              
260             I<Required>E<10> E<8>
261              
262             A valid Algolia application ID for your account.
263              
264             =item - C<api_key>
265              
266             I<Required>E<10> E<8>
267              
268             A valid Algolia api key for your account.
269              
270             =item - C<timeout>
271              
272             I<Optional>E<10> E<8>
273              
274             The number of seconds to wait per request until timing out. Defaults to C<10>.
275              
276             =item - C<retries>
277              
278             I<Optional>E<10> E<8>
279              
280             The number of times to retry requests in cases when Lob returns a 5xx response. Defaults to C<0>.
281              
282             =back
283              
284             =head2 get_indexes
285              
286             Returns a list of all existing indexes.
287              
288             B<Request:>
289              
290             get_indexes();
291              
292             B<Response:>
293              
294             [{
295             createdAt => "2014-12-03T23:20:19.745Z",
296             dataSize => 42,
297             entries => 1,
298             lastBuildTimeS => 0,
299             name => "foo",
300             pendingTask => bless(do{\(my $o = 0)}, "JSON::PP::Boolean"),
301             updatedAt => "2014-12-04T00:41:14.120Z",
302             },
303             {
304             createdAt => "2014-12-03T23:20:18.323Z",
305             dataSize => 36,
306             entries => 1,
307             lastBuildTimeS => 0,
308             name => "bar",
309             pendingTask => bless(do{\(my $o = 0)}, "JSON::PP::Boolean"),
310             updatedAt => "2014-12-04T00:42:13.231Z",
311             }]
312              
313             =head2 browse_index
314              
315             Returns all content from an index.
316              
317             B<Request:>
318              
319             browse_index('foo');
320              
321             B<Response:>
322              
323             {
324             hits => [{ bar => { baz => "bat" }, objectID => 5333220 }],
325             hitsPerPage => 1000,
326             nbHits => 1,
327             nbPages => 1,
328             page => 0,
329             params => "hitsPerPage=1000&attributesToHighlight=&attributesToSnippet=&attributesToRetrieve=*",
330             processingTimeMS => 1,
331             query => "",
332             }
333              
334             =head2 query_index
335              
336             Returns objects that match the query.
337              
338             B<Request:>
339              
340             query_index({ index => 'foo', query => 'bat' });
341              
342             B<Response:>
343              
344             {
345             hits => [
346             { _highlightResult => {
347             bar => {
348             baz => {
349             matchedWords => [ "bat" ],
350             matchLevel => "full",
351             value => "<em>bat</em>"
352             },
353             },
354             },
355             bar => { baz => "bat" },
356             objectID => 5333370,
357             },
358             ],
359             hitsPerPage => 20,
360             nbHits => 1,
361             nbPages => 1,
362             page => 0,
363             params => "query=bat",
364             processingTimeMS => 1,
365             query => "bat",
366             }
367              
368             =head2 query_indexes
369              
370             Query multiple indexes with one API call.
371              
372             B<Request:>
373              
374             query_indexes([
375             { index => 'foo', query => 'baz' },
376             { index => 'foo', query => 'bat' },
377             ]);
378              
379             B<Response:>
380              
381             {
382             results => [
383             { hits => [],
384             hitsPerPage => 20,
385             index => "foo",
386             nbHits => 0,
387             nbPages => 0,
388             page => 0,
389             params => "query=baz",
390             processingTimeMS => 1,
391             query => "baz",
392             },
393             { hits => [
394             { _highlightResult => {
395             bar => {
396             baz => {
397             matchedWords => [ "bat" ],
398             matchLevel => "full",
399             value => "<em>bat</em>"
400             },
401             },
402             },
403             bar => { baz => "bat" },
404             objectID => 5333380,
405             },
406             ],
407             hitsPerPage => 20,
408             index => "foo",
409             nbHits => 1,
410             nbPages => 1,
411             page => 0,
412             params => "query=bat",
413             processingTimeMS => 1,
414             query => "bat",
415             },
416             ],
417             }
418              
419             =head2 clear_index
420              
421             Deletes the index content. Settings and index specific API keys are kept untouched.
422              
423             B<Request:>
424              
425             clear_index('foo');
426              
427             B<Response:>
428              
429             {
430             taskID => 26036480,
431             updatedAt => "2014-12-04T00:53:40.957Z",
432             }
433              
434             =head2 copy_index
435              
436             Copies an existing index. If the destination index already exists, its specific API keys will be preserved and the source index specific API keys will be added.
437              
438             B<Request:>
439              
440             copy_index('foo' => 'foo2');
441              
442             B<Response:>
443              
444             {
445             taskID => 26071750,
446             updatedAt => "2014-12-04T01:16:20.307Z",
447             }
448              
449             =head2 move_index
450              
451             Moves an existing index. If the destination index already exists, its specific API keys will be preserved and the source index specific API keys will be added.
452              
453             B<Request:>
454              
455             move_index('foo' => 'foo2');
456              
457             B<Response:>
458              
459             {
460             taskID => 26079100,
461             updatedAt => "2014-12-04T01:21:01.815Z",
462             }
463              
464             =head2 delete_index
465              
466             Deletes an existing index.
467              
468             B<Request:>
469              
470             delete_index('foo');
471              
472             B<Response:>
473              
474             {
475             taskID => 26040530,
476             deletedAt => "2014-12-04T00:56:00.773Z",
477             }
478              
479             =head2 get_index_settings
480              
481             Retrieves index settings.
482              
483             B<Request:>
484              
485             get_index_settings('foo');
486              
487             B<Response:>
488              
489             {
490             'attributeForDistinct' => undef,
491             'attributesForFaceting' => undef,
492             'attributesToHighlight' => undef,
493             'attributesToIndex' => [ 'bat' ],
494             'attributesToRetrieve' => undef,
495             'attributesToSnippet' => undef,
496             'customRanking' => undef,
497             'highlightPostTag' => '</em>',
498             'highlightPreTag' => '<em>',
499             'hitsPerPage' => 20,
500             'minWordSizefor1Typo' => 4,
501             'minWordSizefor2Typos' => 8,
502             'optionalWords' => undef,
503             'queryType' => 'prefixLast',
504             'ranking' => [
505             'typo',
506             'geo',
507             'words',
508             'proximity',
509             'attribute',
510             'exact',
511             'custom'
512             ],
513             'removeWordsIfNoResults' => 'none',
514             'separatorsToIndex' => '',
515             'unretrievableAttributes' => undef
516             }
517              
518             =head2 update_index_settings
519              
520             Updates part of an index's settings.
521              
522             B<Request:>
523              
524             update_index_settings('foo', { attributesToIndex => ['bat'] });
525              
526             B<Response:>
527              
528             {
529             taskID => 27224430,
530             updatedAt => "2014-12-04T19:52:29.54Z",
531             }
532              
533             =head2 create_index_object
534              
535             Creates a new object in the index, and automatically assigns an Object ID.
536              
537             B<Request:>
538              
539             create_index_object('foo', { bar => { baz => 'bat' }});
540              
541             B<Response:>
542              
543             {
544             objectID => 5333250,
545             taskID => 26026500,
546             createdAt => "2014-12-04T00:47:21.781Z",
547             }
548              
549             =head2 get_index_object
550              
551             Returns one object from the index.
552              
553             B<Request:>
554              
555             get_index_object('foo', 5333250);
556              
557             B<Response:>
558              
559             {
560             objectID => 5333250,
561             delicious => 'limoncello',
562             }
563              
564             =head2 get_index_objects
565              
566             Retrieve several objects with one API call.
567              
568             B<Request:>
569              
570             get_index_objects([
571             { index => 'foo', object => 5333250 },
572             { index => 'foo', object => 5333251 },
573             ]);
574              
575             B<Response:>
576              
577             {
578             results => [{
579             objectID => 5333250,
580             delicious => 'limoncello',
581             },
582             {
583             objectID => 5333251,
584             terrible => 'cabbage',
585             }],
586             }
587              
588             =head2 replace_index_object
589              
590             Creates or replaces an object (if the object does not exist, it will be created). When an object already exists for the specified object ID, the whole object is replaced: existing attributes that are not replaced are deleted.
591              
592             B<Request:>
593              
594             replace_index_object('foo', 5333250, { delicious => 'limoncello' });
595              
596             B<Response:>
597              
598             {
599             objectID => 5333250,
600             taskID => 26034540,
601             updatedAt => "2014-12-04T00:52:32.416Z",
602             }
603              
604             =head2 update_index_object
605              
606             Updates part of an object (if the object does not exist, it will be created. You can avoid an automatic creation of the object by passing C<createIfNotExists=false> as a query argument).
607              
608             B<Request:>
609              
610             update_index_object('foo', 5333251, { another => 'pilsner?' });
611              
612             B<Response:>
613              
614             {
615             objectID => 5333251,
616             taskID => 29453760,
617             updatedAt => "2014-12-06T02:49:40.859Z",
618             }
619              
620             =head2 delete_index_object
621              
622             Deletes an existing object from the index.
623              
624             B<Request:>
625              
626             delete_index_object('foo', 5333251);
627              
628             B<Response:>
629              
630             {
631             objectID => 5333251,
632             taskID => 29453761,
633             deletedAt => "2014-12-11T02:49:40.859Z",
634             }
635              
636             =head2 batch_index_objects
637              
638             To reduce the amount of time spent on network round trips, you can create, update, or delete several objects in one call, using the batch endpoint (all operations are done in the given order).
639              
640             The following methods can be passed into the C<batch_index_objects> method as anonymous subroutines: C<create_index_object>, C<update_index_object>, C<replace_index_object>, and C<delete_index_object>.
641              
642             B<Request:>
643              
644             alg->batch_index_objects('foo', [
645             sub { alg->create_index_object('foo', { hello => 'world' })},
646             sub { alg->create_index_object('foo', { goodbye => 'world' })},
647             ]);
648              
649             B<Response:>
650              
651             {
652             objectIDs => [5698830, 5698840],
653             taskID => 40684520,
654             }
655              
656             B<Request:>
657              
658             alg->batch_index_objects('foo', [
659             sub { alg->update_index_object('foo', 5698830, { 1 => 2 })},
660             sub { alg->update_index_object('foo', 5698840, { 3 => 4 })},
661             ]);
662              
663             B<Response:>
664              
665             {
666             objectIDs => [5698830, 5698840],
667             taskID => 40684521,
668             }
669              
670             B<Request:>
671              
672             alg->batch_index_objects('foo', [
673             sub { alg->delete_index_object('foo', 5698830 )},
674             sub { alg->delete_index_object('foo', 5698840 )},
675             ]);
676              
677             B<Response:>
678              
679             {
680             objectIDs => [5698830, 5698840],
681             taskID => 40684522,
682             }
683              
684             =head2 get_index_keys
685              
686             If an indexName is passed, retrieves API keys that have access to this index with their rights. Otherwise, retrieves all API keys that have access to one index with their rights.
687              
688             B<Request:>
689              
690             get_index_keys();
691              
692             B<Response:>
693              
694             {
695             keys => [
696             {
697             acl => [],
698             index => "pirouette",
699             validity => 0,
700             value => "181b9114149666398628faa37b31cc8d",
701             },
702             {
703             acl => ['browse'],
704             index => "gelato",
705             validity => 0,
706             value => "1428a48214792ac9f6324a823991aa4c",
707             },
708             ],
709             }
710              
711             B<Request:>
712              
713             get_index_keys('pirouette');
714              
715             B<Response:>
716              
717             {
718             keys => [
719             {
720             acl => [],
721             validity => 0,
722             value => "181b9114149666398628faa37b31cc8d",
723             }
724             ],
725             }
726              
727             =head2 get_index_key
728              
729             Returns the rights of a given index specific API key that has been created with the add index specific key API.
730              
731             B<Request:>
732              
733             get_index_key('pirouette', '181b9114149666398628faa37b31cc8d');
734              
735             B<Response:>
736              
737             {
738             acl => [],
739             validity => 0,
740             value => "181b9114149666398628faa37b31cc8d",
741             }
742              
743             =head2 create_index_key
744              
745             Adds a new key that can access this index.
746              
747             B<Request:>
748              
749             create_index_key('pirouette', { acl => ['search']});
750              
751             B<Response:>
752              
753             {
754             createdAt => "2014-12-08T15:54:22.464Z",
755             key => "181b9114149666398628faa37b31cc8d",
756             }
757              
758             =head2 update_index_key
759              
760             Updates a key that can access this index.
761              
762             B<Request:>
763              
764             update_index_key('pirouette', '181b9114149666398628faa37b31cc8d', { acl => ['search', 'browse']});
765              
766             B<Response:>
767              
768             {
769             updatedAt => "2014-12-08T16:39:11.9Z",
770             key => "181b9114149666398628faa37b31cc8d",
771             }
772              
773             =head2 delete_index_key
774              
775             Deletes an index specific API key that has been created with the add index specific key API.
776              
777             B<Request:>
778              
779             delete_index_key('pirouette', '181b9114149666398628faa37b31cc8d');
780              
781             B<Response:>
782              
783             {
784             deletedAt => "2014-12-08T16:40:49.86Z",
785             }
786              
787             =head2 get_task_status
788              
789             Retrieves the status of a given task (published or notPublished). Also returns a C<pendingTask> flag that indicates if the index has remaining task(s) running.
790              
791             B<Request:>
792              
793             get_task_status('foo', 29734242);
794              
795             B<Response:>
796              
797             {
798             pendingTask => bless(do{\(my $o = 0)}, "JSON::PP::Boolean"),
799             status => "published",
800             }
801              
802             =head2 get_keys
803              
804             Retrieves global API keys with their rights. These keys have been created with the add global key API.
805              
806             B<Request:>
807              
808             get_keys();
809              
810             B<Response:>
811              
812             {
813             keys => [
814             {
815             acl => [],
816             validity => 0,
817             value => "28b555c212728a7f462fe96c0e677539",
818             },
819             {
820             acl => [],
821             validity => 0,
822             value => "6ef88c72a6a4fc7e660f8819f111697c",
823             }
824             ],
825             }
826              
827             =head2 get_key
828              
829             Returns the rights of a given global API key that has been created with the add global Key API.
830              
831             B<Request:>
832              
833             get_key('28b555c212728a7f462fe96c0e677539');
834              
835             B<Response:>
836              
837             {
838             acl => [],
839             validity => 0,
840             value => "28b555c212728a7f462fe96c0e677539",
841             }
842              
843             =head2 update_key
844              
845             Updates a global API key.
846              
847             B<Request:>
848              
849             update_key('28b555c212728a7f462fe96c0e677539', { acl => ['search', 'browse']});
850              
851             B<Response:>
852              
853             {
854             updatedAt => "2014-12-08T16:39:11.9Z",
855             key => "28b555c212728a7f462fe96c0e677539",
856             }
857              
858             =head2 delete_key
859              
860             Deletes a global API key that has been created with the add global Key API.
861              
862             B<Request:>
863              
864             delete_key('28b555c212728a7f462fe96c0e677539');
865              
866             B<Response:>
867              
868             {
869             deletedAt => "2014-12-08T16:40:49.86Z",
870             }
871              
872             =head2 get_logs
873              
874             Return last logs.
875              
876             B<Request:>
877              
878             get_logs();
879              
880             B<Response:>
881              
882             {
883             logs => [
884             {
885             answer => "\n{\n \"keys\": [\n ]\n}\n",
886             answer_code => 200,
887             ip => "199.91.170.132",
888             method => "GET",
889             nb_api_calls => 1,
890             processing_time_ms => 1,
891             query_body => "",
892             query_headers => "TE: deflate,gzip;q=0.3\nConnection: TE, close\nHost: 9KV4OFXW8Z.algolia.io\nUser-Agent: libwww-perl/6.08\nContent-Type: application/json\nX-Algolia-API-Key: 28d*****************************\nX-Algolia-Application-Id: 9KV4OFXW8Z\n",
893             sha1 => "b82f8d002ccae799f6629300497725faa670cc7b",
894             timestamp => "2014-12-09T05:08:05Z",
895             url => "/1/keys",
896             },
897             {
898             answer => "\n{\n \"value\": \"3bfccc91bb844f5ba0fc816449a9d340\",\n \"acl\": [\n \"search\"\n ],\n \"validity\": 0\n}\n",
899             answer_code => 200,
900             ip => "199.91.170.132",
901             method => "GET",
902             nb_api_calls => 1,
903             processing_time_ms => 1,
904             query_body => "",
905             query_headers => "TE: deflate,gzip;q=0.3\nConnection: TE, close\nHost: 9KV4OFXW8Z.algolia.io\nUser-Agent: libwww-perl/6.08\nContent-Type: application/json\nX-Algolia-API-Key: 28d*****************************\nX-Algolia-Application-Id: 9KV4OFXW8Z\n",
906             sha1 => "4915e88a309ea42f8f0ee46c9358b57b9a37a3d9",
907             timestamp => "2014-12-09T05:08:04Z",
908             url => "/1/keys/3bfccc91bb844f5ba0fc816449a9d340",
909             },
910             ],
911             }
912              
913             B<Request:>
914              
915             get_logs({
916             offset => 4,
917             length => 2,
918             });
919              
920             B<Response:>
921              
922             {
923             logs => [
924             {
925             answer => "\n{\n \"message\": \"Key does not exist\"\n}\n",
926             answer_code => 404,
927             index => "pirouette",
928             ip => "50.243.54.51",
929             method => "GET",
930             nb_api_calls => 1,
931             processing_time_ms => 1,
932             query_body => "",
933             query_headers => "TE: deflate,gzip;q=0.3\nConnection: TE, close\nHost: 9KV4OFXW8Z.algolia.io\nUser-Agent: libwww-perl/6.07\nContent-Type: application/json\nX-Algolia-API-Key: 28d*****************************\nX-Algolia-Application-Id: 9KV4OFXW8Z\n",
934             sha1 => "e2d3de10f69d8efb16caadaa22c6312ac408ed48",
935             timestamp => "2014-12-08T16:06:32Z",
936             url => "/1/indexes/pirouette/keys/25c005baabd13ab5c3ac14a79c9d5c27",
937             },
938             {
939             answer => "\n{\n \"message\": \"Key does not exist\"\n}\n",
940             answer_code => 404,
941             index => "pirouette",
942             ip => "50.243.54.51",
943             method => "GET",
944             nb_api_calls => 1,
945             processing_time_ms => 1,
946             query_body => "",
947             query_headers => "TE: deflate,gzip;q=0.3\nConnection: TE, close\nHost: 9KV4OFXW8Z.algolia.io\nUser-Agent: libwww-perl/6.07\nContent-Type: application/json\nX-Algolia-API-Key: 28d*****************************\nX-Algolia-Application-Id: 9KV4OFXW8Z\n",
948             sha1 => "d0799be3ccf05d2d5a0c902f6e80917468d5e6ff",
949             timestamp => "2014-12-08T16:06:07Z",
950             url => "/1/indexes/pirouette/keys/b7fbe3bcc26322af222edf2a9ca934ee",
951             },
952             ],
953             }
954              
955             =head2 get_popular_searches
956              
957             Return popular queries for a set of indices.
958              
959             B<Request:>
960              
961             get_popular_searches(['foo']);
962              
963             B<Response:>
964              
965             {
966             lastSearchAt => "2014-12-09T05:00:00.000Z",
967             searchCount => 48,
968             topSearches => [
969             {
970             avgHitCount => 0,
971             avgHitCountWithoutTypos => 0,
972             count => 32,
973             query => "bat"
974             },
975             ],
976             }
977              
978             =head2 get_unpopular_searches
979              
980             Return queries matching 0 records for a set of indices.
981              
982             B<Request:>
983              
984             get_unpopular_searches(['foo']);
985              
986             B<Response:>
987              
988             {
989             lastSearchAt => "2014-12-09T05:00:00.000Z",
990             searchCount => 48,
991             topSearchesNoResuls => [ { count => 16, query => "baz" } ],
992             }
993              
994             =head1 SEE ALSO
995              
996             L<https://www.algolia.com/doc> - the API documentation for L<https://www.algolia.com>.
997              
998             =head1 BUGS
999              
1000             Please report any bugs or feature requests on the bugtracker website
1001             https://github.com/aanari/WebService-Algolia/issues
1002              
1003             When submitting a bug or request, please include a test-file or a
1004             patch to an existing test-file that illustrates the bug or desired
1005             feature.
1006              
1007             =head1 AUTHOR
1008              
1009             Ali Anari <ali@anari.me>
1010              
1011             =head1 COPYRIGHT AND LICENSE
1012              
1013             This software is copyright (c) 2014 by Ali Anari.
1014              
1015             This is free software; you can redistribute it and/or modify it under
1016             the same terms as the Perl 5 programming language system itself.
1017              
1018             =cut