File Coverage

blib/lib/ElasticSearchX/Model.pm
Criterion Covered Total %
statement 20 24 83.3
branch 3 4 75.0
condition n/a
subroutine 6 8 75.0
pod 4 4 100.0
total 33 40 82.5


line stmt bran cond sub pod time code
1             #
2             # This file is part of ElasticSearchX-Model
3             #
4             # This software is Copyright (c) 2016 by Moritz Onken.
5             #
6             # This is free software, licensed under:
7             #
8             # The (three-clause) BSD License
9             #
10             package ElasticSearchX::Model;
11             $ElasticSearchX::Model::VERSION = '1.0.2';
12             # ABSTRACT: Extensible and flexible model for Elasticsearch based on Moose
13 11     11   2484146 use Moose 2.02 ();
  11         195  
  11         232  
14 11     11   43 use Moose::Exporter ();
  11         12  
  11         135  
15 11     11   10529 use ElasticSearchX::Model::Index;
  11         3308  
  11         384  
16 11     11   5465 use ElasticSearchX::Model::Bulk;
  11         30  
  11         2467  
17              
18             Moose::Exporter->setup_import_methods(
19             with_meta => [qw(index analyzer tokenizer filter)],
20             class_metaroles => { class => ['ElasticSearchX::Model::Trait::Class'] },
21             base_class_roles => [qw(ElasticSearchX::Model::Role)],
22             );
23              
24             sub index {
25 21     21 1 227773 my ( $self, $name, @rest ) = @_;
26 21 100       88 if ( !ref $name ) {
    50          
27              
28             # DSL call, where $self is the meta object
29 11         77 return $self->add_index( $name, {@rest} );
30             }
31             elsif ( ref $name eq 'ARRAY' ) {
32 0         0 $self->add_index( $_, {@rest} ) for (@$name);
33 0         0 return;
34             }
35             else {
36              
37             # method call, i.e. $model->index()
38 10         35 my $options = $name->meta->get_index( $rest[0] );
39 10         81 my $index = ElasticSearchX::Model::Index->new(
40             name => $rest[0],
41             %$options, model => $name
42             );
43 10         308 $options->{types} = $index->types;
44 10         112 return $index;
45             }
46             }
47              
48             sub analyzer {
49 2     2 1 127 shift->add_analyzer( shift, {@_} );
50             }
51              
52             sub tokenizer {
53 0     0 1   shift->add_tokenizer( shift, {@_} );
54             }
55              
56             sub filter {
57 0     0 1   shift->add_filter( shift, {@_} );
58             }
59              
60             1;
61              
62             __END__
63              
64             =pod
65              
66             =encoding UTF-8
67              
68             =head1 NAME
69              
70             ElasticSearchX::Model - Extensible and flexible model for Elasticsearch based on Moose
71              
72             =head1 VERSION
73              
74             version 1.0.2
75              
76             =head1 SYNOPSIS
77              
78             package MyModel::Tweet;
79             use Moose;
80             use ElasticSearchX::Model::Document;
81              
82             has message => ( is => 'ro', isa => 'Str' );
83             has date => (
84             is => 'ro',
85             required => 1,
86             isa => 'DateTime',
87             default => sub { DateTime->now }
88             );
89              
90             package MyModel;
91             use Moose;
92             use ElasticSearchX::Model;
93              
94             __PACKAGE__->meta->make_immutable;
95              
96             my $model = MyModel->new;
97             $model->deploy;
98             my $tweet = $model->index('default')->type('tweet')->put({
99             message => 'Hello there!'
100             });
101             print $tweet->_id;
102             $tweet->delete;
103              
104             =head1 DESCRIPTION
105              
106             This is an Elasticsearch to Moose mapper which hides the REST api
107             behind object-oriented api calls. Elasticsearch types and indices
108             are defined using Moose classes and a flexible DSL.
109              
110             Deployment statements for Elasticsearch can be build dynamically
111             using these classes. Results from Elasticsearch inflate automatically
112             to the corresponding Moose classes. Furthermore, it provides
113             sensible defaults.
114              
115             The search API makes the tedious task of building Elasticsearch queries
116             a lot easier.
117              
118             B<< The L<ElasticSearchX::Model::Tutorial> is probably the best place
119             to get started! >>
120              
121             B<< WARNING: This module is being used in production already but I don't
122             consider it being stable in terms of the API and implementation details. >>
123              
124             =head1 DSL
125              
126             =head2 index
127              
128             index twitter => ( namespace => 'MyNamespace', traits => ['MyTrait'] );
129              
130             index facebook => ( types => [qw(FB::User FB::Friends)] );
131              
132             Adds an index to the model. By default there is a C<default>
133             index, which will be removed once you add custom indices.
134              
135             See L<ElasticSearchX::Model::Index/ATTRIBUTES> for available options.
136              
137             =head2 analyzer
138              
139             =head2 tokenizer
140              
141             =head2 filter
142              
143             analyzer lowercase => ( tokenizer => 'keyword', filter => 'lowercase' );
144              
145             tokenizer camelcase => (
146             type => 'pattern',
147             pattern => "([^\\p{L}\\d]+)|(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[\\p{L}&&[^\\p{Lu}]])(?=\\p{Lu})|(?<=\\p{Lu})(?=\\p{Lu}[\\p{L}&&[^\\p{Lu}]])"
148             );
149             analyzer camelcase => (
150             type => 'custom',
151             tokenizer => 'camelcase',
152             filter => ['lowercase', 'unique']
153             );
154              
155             Adds analyzers, tokenizers or filters to all indices. They can
156             then be used in attributes of L<ElasticSearchX::Model::Document> classes.
157              
158             =head1 ATTRIBUTES
159              
160             =head2 es
161              
162             Builds and holds the L<ElasticSearch> object. Valid values are:
163              
164             =over
165              
166             =item B<:9200>
167              
168             Connect to a server on C<127.0.0.1>, port C<9200> with the C<httptiny>
169             transport class and a timeout of 30 seconds.
170              
171             =item B<[qw(:9200 12.12.12.12:9200)]>
172              
173             Connect to C<127.0.0.1:9200> and C<12.12.12.12:9200> with the same
174             defaults as above.
175              
176             =item B<{ %args }>
177              
178             Passes C<%args> directly to the L<ElasticSearch> constructor.
179              
180             =back
181              
182             =head2 bulk
183              
184             my $bulk = $model->bulk( size => 100 );
185             $bulk->put($tweet);
186             $bulk->commit; # optional
187              
188             Returns an instance of L<ElasticSearchX::Model::Bulk>.
189              
190             =head1 METHODS
191              
192             =head2 index
193              
194             my $index = $model->index('twitter');
195              
196             Returns an L<ElasticSearchX::Model::Index> object.
197              
198             =head2 deploy
199              
200             C<deploy> pushes the mapping to the Elasticsearch server. It will
201             automatically try to upgrade your mapping if the types already
202             exists. However, this might not be possible in case you changes
203             a field from one data type to another and Elasticsearch cannot
204             figure out how to translate it. In this case C<deploy> will
205             throw an error message.
206              
207             To create the indices from scratch, pass C<< delete => 1 >>.
208             B<< This will delete all the data in your indices. >>
209              
210             $model->deploy( delete => 1 );
211              
212             =head2 es_version
213              
214             if($model->es_version > 0.02) { ... }
215              
216             Returns the L<version> number of the Elasticsearch server you are currently
217             connected to. Elasticsearch uses Semantic Versioning. However, release candidates
218             have a special syntax. For example, the version 0.20.0.RC1 would be parsed
219             as 0.020_000_001.
220              
221             =head1 PERFORMANCE CONSIDERATIONS
222              
223             Creating objects is a quite expensive operation. If you are
224             crawling through large amounts of data, you will gain a huge
225             speed improvement by not inflating the results to their
226             document classes (see L<ElasticSearchX::Model::Document::Set/raw>).
227              
228             =head1 AUTHOR
229              
230             Moritz Onken
231              
232             =head1 COPYRIGHT AND LICENSE
233              
234             This software is Copyright (c) 2016 by Moritz Onken.
235              
236             This is free software, licensed under:
237              
238             The (three-clause) BSD License
239              
240             =cut