File Coverage

blib/lib/ElasticSearchX/Model/Document/Mapping.pm
Criterion Covered Total %
statement 27 27 100.0
branch 9 10 90.0
condition 9 11 81.8
subroutine 5 5 100.0
pod 0 1 0.0
total 50 54 92.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) 2019 by Moritz Onken.
5             #
6             # This is free software, licensed under:
7             #
8             # The (three-clause) BSD License
9             #
10             package ElasticSearchX::Model::Document::Mapping;
11             $ElasticSearchX::Model::Document::Mapping::VERSION = '2.0.1';
12 7     7   52 use strict;
  7         18  
  7         203  
13 7     7   36 use warnings;
  7         20  
  7         222  
14 7     7   38 use Moose::Util::TypeConstraints;
  7         14  
  7         59  
15              
16             our %MAPPING = ();
17              
18             sub maptc {
19 87     87 0 7935 my ( $attr, $constraint ) = @_;
20 87   66     246 $constraint ||= find_type_constraint('Str');
21 87         2935 ( my $name = $constraint->name ) =~ s/\[.*\]/\[\]/;
22 87         13492 my $sub = $MAPPING{$name};
23 87         136 my %ret;
24 87 100 66     1532 if ( !$sub && $constraint->has_parent ) {
    50          
25 45         2928 %ret = maptc( $attr, $constraint->parent );
26             }
27             elsif ($sub) {
28 42         115 %ret = $sub->( $attr, $constraint );
29             }
30              
31 87 100       240 if ( $ret{type} ne 'string' ) {
32 20         43 delete $ret{ignore_above};
33             }
34              
35 87         388 return %ret;
36             }
37              
38             $MAPPING{Any} = sub {
39              
40             my ( $attr, $tc ) = @_;
41              
42             my %mapping = (
43             $attr->index ? ( index => $attr->index ) : (),
44             $attr->type eq 'object' ? ( dynamic => $attr->dynamic ) : (),
45             $attr->boost ? ( boost => $attr->boost ) : (),
46             !$attr->include_in_all ? ( include_in_all => \0 ) : (),
47             type => 'string',
48             $attr->analyzer->[0] ? ( analyzer => $attr->analyzer->[0] ) : (),
49             );
50             return _set_doc_values(%mapping);
51             };
52              
53             $MAPPING{Str} = sub {
54             my ( $attr, $tc ) = @_;
55             my %term
56             = $attr->term_vector ? ( term_vector => $attr->term_vector ) : ();
57             if ( $attr->index && $attr->index eq 'analyzed' || @{ $attr->analyzer } )
58             {
59             my @analyzer = @{ $attr->{analyzer} };
60             push( @analyzer, 'standard' ) unless (@analyzer);
61             return _set_doc_values(
62             type => 'multi_field',
63             fields => {
64             (
65             $attr->not_analyzed
66             ? (
67             $attr->name => {
68             index => 'not_analyzed',
69             ignore_above => 2048,
70             doc_values => \1,
71             !$attr->include_in_all
72             ? ( include_in_all => \0 )
73             : (),
74             $attr->boost ? ( boost => $attr->boost ) : (),
75             type => $attr->type,
76             }
77             )
78             : ()
79             ),
80             analyzed => {
81             store => $attr->store,
82             index => 'analyzed',
83             type => $attr->type,
84             $attr->boost ? ( boost => $attr->boost ) : (),
85             %term,
86             analyzer => shift @analyzer,
87             $attr->type eq 'string'
88             ? ( fielddata => { format => 'disabled' } )
89             : (),
90             },
91             (
92             map {
93             $_ => {
94             store => $attr->store,
95             index => 'analyzed',
96             type => $attr->type,
97             $attr->boost ? ( boost => $attr->boost ) : (),
98             %term,
99             analyzer => $_
100             }
101             } @analyzer
102             )
103             }
104             );
105             }
106             return _set_doc_values(
107             index => 'not_analyzed',
108             ignore_above => 2048,
109             %term, maptc( $attr, $tc->parent )
110             );
111             };
112              
113             $MAPPING{Num} = sub {
114             my ( $attr, $tc ) = @_;
115             return _set_doc_values( maptc( $attr, $tc->parent ), type => 'float' );
116             };
117              
118             $MAPPING{Int} = sub {
119             my ( $attr, $tc ) = @_;
120             return _set_doc_values( maptc( $attr, $tc->parent ), type => 'integer' );
121             };
122              
123             $MAPPING{Bool} = sub {
124             my ( $attr, $tc ) = @_;
125             return _set_doc_values( maptc( $attr, $tc->parent ), type => 'boolean' );
126             };
127              
128             $MAPPING{ScalarRef} = sub {
129             my ( $attr, $tc ) = @_;
130             return maptc( $attr, find_type_constraint('Str') );
131             };
132              
133             $MAPPING{ArrayRef} = sub {
134             my ( $attr, $tc ) = @_;
135             return maptc( $attr, find_type_constraint('Str') );
136             };
137              
138             $MAPPING{'ArrayRef[]'} = sub {
139             my ( $attr, $tc ) = @_;
140             my $param = $tc->type_parameter;
141             return maptc( $attr, $param );
142             };
143              
144             $MAPPING{'MooseX::Types::Structured::Dict[]'} = sub {
145             my ( $attr, $constraint ) = @_;
146             my %constraints = @{ $constraint->type_constraints };
147             my $value = {};
148             while ( my ( $k, $v ) = each %constraints ) {
149             $value->{$k} = { maptc( $attr, $v ) };
150             }
151             my %mapping = maptc( $attr, $constraint->parent );
152             delete $mapping{$_} for (qw(index boost store));
153             return (
154             %mapping,
155             type => $attr->type eq 'nested' ? 'nested' : 'object',
156             dynamic => \( $attr->dynamic ),
157             properties => $value,
158             $attr->include_in_root ? ( include_in_root => \1 ) : (),
159             $attr->include_in_parent ? ( include_in_parent => \1 ) : (),
160             );
161             };
162              
163             $MAPPING{'MooseX::Types::Structured::Optional[]'} = sub {
164             my ( $attr, $constraint ) = @_;
165             return maptc( $attr, $constraint->type_parameter );
166             };
167              
168             $MAPPING{'MooseX::Types::ElasticSearch::Location'} = sub {
169             my ( $attr, $tc ) = @_;
170             my %mapping = maptc( $attr, $tc->parent );
171             delete $mapping{$_} for (qw(index store));
172             return ( %mapping, type => 'geo_point', doc_values => \1 );
173             };
174              
175             $MAPPING{'ElasticSearchX::Model::Document::Types::Type[]'} = sub {
176             my ( $attr, $constraint ) = @_;
177             return (
178             %{ $constraint->type_parameter->class->meta->mapping },
179             dynamic => \( $attr->dynamic ),
180             $attr->include_in_root ? ( include_in_root => \1 ) : (),
181             $attr->include_in_parent ? ( include_in_parent => \1 ) : (),
182             type => $attr->type eq 'nested' ? 'nested' : 'object',
183             );
184             };
185              
186             $MAPPING{'DateTime'} = sub {
187             my ( $attr, $tc ) = @_;
188             return _set_doc_values(
189             maptc( $attr, $tc->parent ),
190             type => 'date',
191             doc_values => \1
192             );
193             };
194              
195             sub _set_doc_values {
196 26     26   77 my %mapping = @_;
197              
198 26 100 100     125 if ( $mapping{type} eq 'string'
    100 100        
199             && ( $mapping{index} || 'analyzed' ) eq 'analyzed' )
200             {
201 12         25 delete $mapping{doc_values};
202             }
203             elsif ( $mapping{type} eq 'multi_field' ) {
204 5         10 delete $mapping{fielddata};
205             }
206             else {
207 9         20 $mapping{doc_values} = \1;
208 9         15 delete $mapping{fielddata};
209             }
210 26         119 return %mapping
211              
212             }
213              
214             __END__
215              
216             =pod
217              
218             =encoding UTF-8
219              
220             =head1 NAME
221              
222             ElasticSearchX::Model::Document::Mapping
223              
224             =head1 VERSION
225              
226             version 2.0.1
227              
228             =head1 AUTHOR
229              
230             Moritz Onken
231              
232             =head1 COPYRIGHT AND LICENSE
233              
234             This software is Copyright (c) 2019 by Moritz Onken.
235              
236             This is free software, licensed under:
237              
238             The (three-clause) BSD License
239              
240             =cut