27
27
import org .elasticsearch .common .xcontent .XContentType ;
28
28
import org .slf4j .Logger ;
29
29
import org .slf4j .LoggerFactory ;
30
+
30
31
import org .springframework .core .io .ClassPathResource ;
31
32
import org .springframework .data .annotation .Transient ;
32
- import org .springframework .data .elasticsearch .annotations .*;
33
+ import org .springframework .data .elasticsearch .annotations .CompletionContext ;
34
+ import org .springframework .data .elasticsearch .annotations .CompletionField ;
35
+ import org .springframework .data .elasticsearch .annotations .DateFormat ;
36
+ import org .springframework .data .elasticsearch .annotations .DynamicTemplates ;
37
+ import org .springframework .data .elasticsearch .annotations .Field ;
38
+ import org .springframework .data .elasticsearch .annotations .FieldType ;
39
+ import org .springframework .data .elasticsearch .annotations .GeoPointField ;
40
+ import org .springframework .data .elasticsearch .annotations .InnerField ;
41
+ import org .springframework .data .elasticsearch .annotations .Mapping ;
42
+ import org .springframework .data .elasticsearch .annotations .MultiField ;
33
43
import org .springframework .data .elasticsearch .core .completion .Completion ;
34
44
import org .springframework .data .elasticsearch .core .convert .ElasticsearchConverter ;
35
45
import org .springframework .data .elasticsearch .core .geo .GeoPoint ;
36
46
import org .springframework .data .elasticsearch .core .mapping .ElasticsearchPersistentEntity ;
37
47
import org .springframework .data .elasticsearch .core .mapping .ElasticsearchPersistentProperty ;
38
48
import org .springframework .data .mapping .PropertyHandler ;
39
- import org .springframework .data .mapping .model .SimpleTypeHolder ;
40
49
import org .springframework .data .util .TypeInformation ;
41
50
import org .springframework .lang .Nullable ;
42
51
import org .springframework .util .StringUtils ;
61
70
*/
62
71
class MappingBuilder {
63
72
64
- public static final String FIELD_DATA = "fielddata" ;
65
- public static final String FIELD_STORE = "store" ;
66
- public static final String FIELD_TYPE = "type" ;
67
- public static final String FIELD_INDEX = "index" ;
68
- public static final String FIELD_FORMAT = "format" ;
69
- public static final String FIELD_SEARCH_ANALYZER = "search_analyzer" ;
70
- public static final String FIELD_INDEX_ANALYZER = "analyzer" ;
71
- public static final String FIELD_NORMALIZER = "normalizer" ;
72
- public static final String FIELD_PROPERTIES = "properties" ;
73
- public static final String FIELD_PARENT = "_parent" ;
74
- public static final String FIELD_COPY_TO = "copy_to" ;
75
- public static final String FIELD_CONTEXT_NAME = "name" ;
76
- public static final String FIELD_CONTEXT_TYPE = "type" ;
77
- public static final String FIELD_CONTEXT_PRECISION = "precision" ;
78
- public static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates" ;
79
-
80
- public static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators" ;
81
- public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments" ;
82
- public static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length" ;
83
- public static final String COMPLETION_CONTEXTS = "contexts" ;
84
-
85
- public static final String TYPE_VALUE_KEYWORD = "keyword" ;
86
- public static final String TYPE_VALUE_GEO_POINT = "geo_point" ;
87
- public static final String TYPE_VALUE_COMPLETION = "completion" ;
88
- public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix" ;
89
- public static final String TYPE_VALUE_GEO_HASH_PRECISION = "geohash_precision" ;
73
+ private static final String FIELD_DATA = "fielddata" ;
74
+ private static final String FIELD_STORE = "store" ;
75
+ private static final String FIELD_TYPE = "type" ;
76
+ private static final String FIELD_INDEX = "index" ;
77
+ private static final String FIELD_FORMAT = "format" ;
78
+ private static final String FIELD_SEARCH_ANALYZER = "search_analyzer" ;
79
+ private static final String FIELD_INDEX_ANALYZER = "analyzer" ;
80
+ private static final String FIELD_NORMALIZER = "normalizer" ;
81
+ private static final String FIELD_PROPERTIES = "properties" ;
82
+ private static final String FIELD_PARENT = "_parent" ;
83
+ private static final String FIELD_COPY_TO = "copy_to" ;
84
+ private static final String FIELD_CONTEXT_NAME = "name" ;
85
+ private static final String FIELD_CONTEXT_TYPE = "type" ;
86
+ private static final String FIELD_CONTEXT_PRECISION = "precision" ;
87
+ private static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates" ;
88
+
89
+ private static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators" ;
90
+ private static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments" ;
91
+ private static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length" ;
92
+ private static final String COMPLETION_CONTEXTS = "contexts" ;
93
+
94
+ private static final String TYPE_VALUE_KEYWORD = "keyword" ;
95
+ private static final String TYPE_VALUE_GEO_POINT = "geo_point" ;
96
+ private static final String TYPE_VALUE_COMPLETION = "completion" ;
97
+
90
98
private static final Logger logger = LoggerFactory .getLogger (ElasticsearchRestTemplate .class );
91
- private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = SimpleTypeHolder . DEFAULT ;
99
+
92
100
private final ElasticsearchConverter elasticsearchConverter ;
93
101
94
102
MappingBuilder (ElasticsearchConverter elasticsearchConverter ) {
@@ -101,7 +109,7 @@ class MappingBuilder {
101
109
* @return JSON string
102
110
* @throws IOException
103
111
*/
104
- String buildMapping (Class <?> clazz ) throws IOException {
112
+ String buildPropertyMapping (Class <?> clazz ) throws IOException {
105
113
106
114
ElasticsearchPersistentEntity <?> entity = elasticsearchConverter .getMappingContext ()
107
115
.getRequiredPersistentEntity (clazz );
@@ -157,70 +165,76 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten
157
165
return ;
158
166
}
159
167
160
- if (property .isAnnotationPresent (Mapping .class )) {
168
+ buildPropertyMapping (builder , isRootObject , property );
169
+ } catch (IOException e ) {
170
+ logger .warn ("error mapping property with name {}" , property .getName (), e );
171
+ }
172
+ });
173
+ }
161
174
162
- String mappingPath = property .getRequiredAnnotation (Mapping .class ).mappingPath ();
163
- if (!StringUtils .isEmpty (mappingPath )) {
175
+ if (writeNestedProperties ) {
176
+ builder .endObject ().endObject ();
177
+ }
178
+ }
164
179
165
- ClassPathResource mappings = new ClassPathResource (mappingPath );
166
- if (mappings .exists ()) {
167
- builder .rawField (property .getFieldName (), mappings .getInputStream (), XContentType .JSON );
168
- return ;
169
- }
170
- }
171
- }
180
+ private void buildPropertyMapping (XContentBuilder builder , boolean isRootObject ,
181
+ ElasticsearchPersistentProperty property ) throws IOException {
172
182
173
- boolean isGeoPointProperty = isGeoPointProperty (property );
174
- boolean isCompletionProperty = isCompletionProperty (property );
175
- boolean isNestedOrObjectProperty = isNestedOrObjectProperty (property );
183
+ if (property .isAnnotationPresent (Mapping .class )) {
176
184
177
- Field fieldAnnotation = property .findAnnotation ( Field .class );
178
- if (!isGeoPointProperty && ! isCompletionProperty && property . isEntity () && hasRelevantAnnotation ( property )) {
185
+ String mappingPath = property .getRequiredAnnotation ( Mapping .class ). mappingPath ( );
186
+ if (!StringUtils . isEmpty ( mappingPath )) {
179
187
180
- if (fieldAnnotation == null ) {
181
- return ;
182
- }
188
+ ClassPathResource mappings = new ClassPathResource (mappingPath );
189
+ if (mappings .exists ()) {
190
+ builder .rawField (property .getFieldName (), mappings .getInputStream (), XContentType .JSON );
191
+ return ;
192
+ }
193
+ }
194
+ }
183
195
184
- Iterator <? extends TypeInformation <?>> iterator = property .getPersistentEntityTypes ().iterator ();
185
- ElasticsearchPersistentEntity <?> persistentEntity = iterator .hasNext ()
186
- ? elasticsearchConverter .getMappingContext ().getPersistentEntity (iterator .next ())
187
- : null ;
196
+ boolean isGeoPointProperty = isGeoPointProperty (property );
197
+ boolean isCompletionProperty = isCompletionProperty (property );
198
+ boolean isNestedOrObjectProperty = isNestedOrObjectProperty (property );
188
199
189
- mapEntity ( builder , persistentEntity , false , property .getFieldName (), isNestedOrObjectProperty ,
190
- fieldAnnotation . type (), fieldAnnotation );
200
+ Field fieldAnnotation = property .findAnnotation ( Field . class );
201
+ if (! isGeoPointProperty && ! isCompletionProperty && property . isEntity () && hasRelevantAnnotation ( property )) {
191
202
192
- if (isNestedOrObjectProperty ) {
193
- return ;
194
- }
195
- }
203
+ if (fieldAnnotation == null ) {
204
+ return ;
205
+ }
196
206
197
- MultiField multiField = property .findAnnotation (MultiField .class );
207
+ Iterator <? extends TypeInformation <?>> iterator = property .getPersistentEntityTypes ().iterator ();
208
+ ElasticsearchPersistentEntity <?> persistentEntity = iterator .hasNext ()
209
+ ? elasticsearchConverter .getMappingContext ().getPersistentEntity (iterator .next ())
210
+ : null ;
198
211
199
- if (isGeoPointProperty ) {
200
- applyGeoPointFieldMapping (builder , property );
201
- return ;
202
- }
212
+ mapEntity (builder , persistentEntity , false , property .getFieldName (), isNestedOrObjectProperty ,
213
+ fieldAnnotation .type (), fieldAnnotation );
203
214
204
- if (isCompletionProperty ) {
205
- CompletionField completionField = property . findAnnotation ( CompletionField . class ) ;
206
- applyCompletionFieldMapping ( builder , property , completionField );
207
- }
215
+ if (isNestedOrObjectProperty ) {
216
+ return ;
217
+ }
218
+ }
208
219
209
- if (isRootObject && fieldAnnotation != null && property .isIdProperty ()) {
210
- applyDefaultIdFieldMapping (builder , property );
211
- } else if (multiField != null ) {
212
- addMultiFieldMapping (builder , property , multiField , isNestedOrObjectProperty );
213
- } else if (fieldAnnotation != null ) {
214
- addSingleFieldMapping (builder , property , fieldAnnotation , isNestedOrObjectProperty );
215
- }
216
- } catch (IOException e ) {
217
- logger .warn ("error mapping property with name {}" , property .getName (), e );
218
- }
219
- });
220
+ MultiField multiField = property .findAnnotation (MultiField .class );
221
+
222
+ if (isGeoPointProperty ) {
223
+ applyGeoPointFieldMapping (builder , property );
224
+ return ;
220
225
}
221
226
222
- if (writeNestedProperties ) {
223
- builder .endObject ().endObject ();
227
+ if (isCompletionProperty ) {
228
+ CompletionField completionField = property .findAnnotation (CompletionField .class );
229
+ applyCompletionFieldMapping (builder , property , completionField );
230
+ }
231
+
232
+ if (isRootObject && fieldAnnotation != null && property .isIdProperty ()) {
233
+ applyDefaultIdFieldMapping (builder , property );
234
+ } else if (multiField != null ) {
235
+ addMultiFieldMapping (builder , property , multiField , isNestedOrObjectProperty );
236
+ } else if (fieldAnnotation != null ) {
237
+ addSingleFieldMapping (builder , property , fieldAnnotation , isNestedOrObjectProperty );
224
238
}
225
239
}
226
240
@@ -321,6 +335,7 @@ private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersiste
321
335
322
336
private void addFieldMappingParameters (XContentBuilder builder , Object annotation , boolean nestedOrObjectField )
323
337
throws IOException {
338
+
324
339
boolean index = true ;
325
340
boolean store = false ;
326
341
boolean fielddata = false ;
0 commit comments