File Coverage

blib/lib/Elastic/Doc.pm
Criterion Covered Total %
statement 13 27 48.1
branch 0 8 0.0
condition 0 6 0.0
subroutine 5 6 83.3
pod 2 3 66.6
total 20 50 40.0


line stmt bran cond sub pod time code
1             package Elastic::Doc;
2             $Elastic::Doc::VERSION = '0.51';
3 23     23   72227 use Moose();
  23         51  
  23         599  
4 23     23   109 use Moose::Exporter;
  23         38  
  23         214  
5 23     23   1317 use namespace::autoclean;
  23         45  
  23         240  
6              
7             Moose::Exporter->setup_import_methods(
8                 with_meta => [ 'has_mapping', 'apply_field_settings' ],
9                 class_metaroles => {
10                     class => ['Elastic::Model::Meta::Class::Doc'],
11                     attribute => ['Elastic::Model::Trait::Field'],
12                 },
13                 also => 'Moose',
14             );
15              
16             #===================================
17             sub init_meta {
18             #===================================
19 166     166 0 258460     shift;
20 166         893     my $meta = Moose->init_meta(@_);
21 166         650906     Moose::Util::apply_all_roles( $meta, 'Elastic::Model::Role::Doc' );
22             }
23              
24             #===================================
25 4     4 1 10509 sub has_mapping { shift->mapping(@_) }
26             #===================================
27              
28             #===================================
29             sub apply_field_settings {
30             #===================================
31 0     0 1       my $meta = shift;
32              
33 0 0 0           if ( @_ == 1 and $_[0] eq '-exclude' ) {
34 0                   for ( $meta->get_all_attributes ) {
35                         next
36 0 0 0                       if $_->does('Elastic::Model::Trait::Field')
37                             or $_->does('Elastic::Model::Trait::Exclude');
38 0                       Moose::Util::apply_all_roles( $_,
39                             'Elastic::Model::Trait::Exclude' );
40                     }
41 0                   return;
42                 }
43              
44 0 0             my %settings = @_ == 1 ? %{ shift() } : @_;
  0            
45 0               for my $name ( keys %settings ) {
46 0 0                 my $attr = $meta->get_attribute($name)
47                         or die "Couldn't find attr ($name) in class ("
48                         . $meta->name
49                         . ") in apply_field_settings()";
50 0                   Moose::Util::ensure_all_roles( $attr,
51                         'Elastic::Model::Trait::Field' );
52 0                   my $params = $settings{$name};
53 0                   for ( keys %$params ) {
54 0                       $attr->$_( $params->{$_} );
55                     }
56                 }
57             }
58              
59             1;
60              
61             =pod
62            
63             =encoding UTF-8
64            
65             =head1 NAME
66            
67             Elastic::Doc - Adds Elastic::Model functionality to your object classes
68            
69             =head1 VERSION
70            
71             version 0.51
72            
73             =head1 SYNOPSIS
74            
75             =head2 Simple class definition
76            
77             package MyApp::User;
78            
79             use Elastic::Doc;
80            
81             has 'name' => (
82             is => 'rw',
83             isa => 'Str'
84             );
85            
86             no Elastic::Doc;
87            
88             =head2 More complex class definition
89            
90             package MyApp::User;
91            
92             use Elastic::Doc;
93            
94             has_mapping {
95             _ttl => { # delete documents/object after 2 hours
96             enabled => 1,
97             default => '2h'
98             }
99             };
100            
101             has 'user' => (
102             is => 'ro',
103             isa => 'MyApp::User'
104             );
105            
106             has 'title' => (
107             is => 'rw',
108             isa => 'Str',
109             analyzer => 'edge_ngrams' # use custom analyzer
110             );
111            
112             has 'body' => (
113             is => 'rw',
114             isa => 'Str',
115             analyzer => 'english', # use builtin analyzer
116             );
117            
118             has 'created' => (
119             is => 'ro',
120             isa => 'DateTime',
121             default => sub { DateTime->new }
122             );
123            
124             has 'tag' => (
125             is => 'ro',
126             isa => 'Str',
127             index => 'not_analyzed' # index exact value
128             );
129            
130             no Elastic::Doc;
131            
132             =head1 DESCRIPTION
133            
134             Elastic::Doc prepares your object classes (eg C<MyApp::User>) for storage in
135             Elasticsearch, by:
136            
137             =over
138            
139             =item *
140            
141             applying L<Elastic::Model::Role::Doc> to your class and
142             L<Elastic::Model::Meta::Doc> to its metaclass
143            
144             =item *
145            
146             adding keywords to your attribute declarations, to give you control over how
147             they are indexed (see L<Elastic::Manual::Attributes>)
148            
149             =item *
150            
151             wrapping your accessors to allow auto-inflation of embedded objects (see
152             L<Elastic::Model::Meta::Instance>).
153            
154             =item *
155            
156             exporting the L</"has_mapping"> function to allow you to customize the
157             special "meta-fields" in the type mapping in Elasticsearch
158            
159             =back
160            
161             =head1 INTRODUCTION TO Elastic::Model
162            
163             If you are not familiar with L<Elastic::Model>, you should start by reading
164             L<Elastic::Manual::Intro>.
165            
166             The rest of the documentation on this page explains how to use the
167             L<Elastic::Doc> module itself.
168            
169             =head1 EXPORTED FUNCTIONS
170            
171             =head2 has_mapping
172            
173             C<has_mapping> can be used to customize the special "meta-fields" (ie not
174             attr/field-specific) in the type mapping. For instance:
175            
176             has_mapping {
177             _source => {
178             includes => ['path1.*','path2.*'],
179             excludes => ['path3.*']
180             },
181             _ttl => {
182             enabled => 1,
183             default => '2h'
184             },
185             numeric_detection => 1,
186             date_detection => 0,
187             };
188            
189             B<Warning:> Use C<has_mapping> with caution. L<Elastic::Model> requires
190             certain settings to be active to work correctly.
191            
192             See the "Fields" section in L<Mapping|http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-fields.html> and
193             L<Root object type|http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-root-object-type.html>
194             for more information about what options can be configured.
195            
196             =head2 apply_field_settings
197            
198             package MyApp::User;
199            
200             use Elastic::Doc;
201             with 'MyApp::Role::Foo';
202            
203             apply_field_settings {
204             field_1 => { type => 'string' },
205             field_2 => { exclude => 1 }
206             };
207            
208             When you apply a role to your Elastic::Doc class, you may not be able to
209             configure the attributes directly in the role (eg if the role comes from
210             CPAN).
211            
212             You can use C<apply_field_settings> in your doc class to add any of the
213             settings specified in L<Elastic::Manual::Attributes>. Alternatively,
214             if you don't want any of the imported attributes to be persisted to
215             Elasticsearch, then you can specify:
216            
217             apply_field_settings '-exclude';
218            
219             B<Note:> the C<-exclude> is applied to all attributes applied thus far, which
220             don't already do L<Elastic::Model::Trait::Field>. So you
221             can then apply other roles and have another C<apply_field_settings> statement
222             later in your module.
223            
224             If you DO have access to the role, then the preferred way to configure
225             attributes is with the C<ElasticField> trait:
226            
227             package MyApp::Role::Foo;
228            
229             use Moose::Role;
230            
231             has 'name' => (
232             traits => ['ElasticField'],
233             is => 'rw',
234             index => 'not_analyzed'
235             );
236            
237             C<ElasticField> is the short name for L<Elastic::Model::Trait::Field>.
238            
239             =head1 SEE ALSO
240            
241             =over
242            
243             =item *
244            
245             L<Elastic::Model::Role::Doc>
246            
247             =item *
248            
249             L<Elastic::Model>
250            
251             =item *
252            
253             L<Elastic::Meta::Trait::Field>
254            
255             =item *
256            
257             L<Elastic::Model::TypeMap::Default>
258            
259             =item *
260            
261             L<Elastic::Model::TypeMap::Moose>
262            
263             =item *
264            
265             L<Elastic::Model::TypeMap::Objects>
266            
267             =item *
268            
269             L<Elastic::Model::TypeMap::Structured>
270            
271             =item *
272            
273             L<Elastic::Model::TypeMap::ES>
274            
275             =item *
276            
277             L<Elastic::Model::TypeMap::Common>
278            
279             =back
280            
281             =head1 AUTHOR
282            
283             Clinton Gormley <drtech@cpan.org>
284            
285             =head1 COPYRIGHT AND LICENSE
286            
287             This software is copyright (c) 2015 by Clinton Gormley.
288            
289             This is free software; you can redistribute it and/or modify it under
290             the same terms as the Perl 5 programming language system itself.
291            
292             =cut
293              
294             __END__
295            
296             # ABSTRACT: Adds Elastic::Model functionality to your object classes
297            
298            
299