Skip to content

Commit aba14c5

Browse files
authored
Add enabled mapping parameter.
Original PullRequest #1652 Closes #1370
1 parent b7a23ed commit aba14c5

File tree

4 files changed

+167
-104
lines changed

4 files changed

+167
-104
lines changed

Diff for: src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
*/
1616
package org.springframework.data.elasticsearch.annotations;
1717

18-
import java.lang.annotation.*;
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Inherited;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
1924
import org.springframework.data.annotation.Persistent;
2025

2126
/**
@@ -26,9 +31,15 @@
2631
@Persistent
2732
@Inherited
2833
@Retention(RetentionPolicy.RUNTIME)
29-
@Target({ElementType.TYPE, ElementType.FIELD})
34+
@Target({ ElementType.TYPE, ElementType.FIELD })
3035
public @interface Mapping {
3136

3237
String mappingPath() default "";
3338

39+
/**
40+
* whether mappings are enabled
41+
*
42+
* @since 4.2
43+
*/
44+
boolean enabled() default true;
3445
}

Diff for: src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java

+51-14
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.slf4j.LoggerFactory;
3232
import org.springframework.core.io.ClassPathResource;
3333
import org.springframework.data.annotation.Transient;
34-
import org.springframework.data.elasticsearch.ElasticsearchException;
3534
import org.springframework.data.elasticsearch.annotations.*;
3635
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
3736
import org.springframework.data.elasticsearch.core.ResourceUtil;
@@ -66,6 +65,8 @@
6665
*/
6766
public class MappingBuilder {
6867

68+
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
69+
6970
private static final String FIELD_INDEX = "index";
7071
private static final String FIELD_PROPERTIES = "properties";
7172
@Deprecated private static final String FIELD_PARENT = "_parent";
@@ -88,7 +89,7 @@ public class MappingBuilder {
8889

8990
private static final String JOIN_TYPE_RELATIONS = "relations";
9091

91-
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
92+
private static final String MAPPING_ENABLED = "enabled";
9293

9394
private final ElasticsearchConverter elasticsearchConverter;
9495

@@ -100,9 +101,9 @@ public MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
100101
* builds the Elasticsearch mapping for the given clazz.
101102
*
102103
* @return JSON string
103-
* @throws ElasticsearchException on errors while building the mapping
104+
* @throws MappingException on errors while building the mapping
104105
*/
105-
public String buildPropertyMapping(Class<?> clazz) throws ElasticsearchException {
106+
public String buildPropertyMapping(Class<?> clazz) throws MappingException {
106107

107108
try {
108109
ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.getMappingContext()
@@ -125,15 +126,23 @@ public String buildPropertyMapping(Class<?> clazz) throws ElasticsearchException
125126
.close();
126127

127128
return builder.getOutputStream().toString();
128-
} catch (MappingException | IOException e) {
129-
throw new ElasticsearchException("could not build mapping", e);
129+
} catch (IOException e) {
130+
throw new MappingException("could not build mapping", e);
130131
}
131132
}
132133

133134
private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersistentEntity<?> entity,
134135
boolean isRootObject, String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType,
135136
@Nullable Field parentFieldAnnotation, @Nullable DynamicMapping dynamicMapping) throws IOException {
136137

138+
if (entity != null && entity.isAnnotationPresent(Mapping.class)) {
139+
140+
if (!entity.getRequiredAnnotation(Mapping.class).enabled()) {
141+
builder.field(MAPPING_ENABLED, false);
142+
return;
143+
}
144+
}
145+
137146
boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField);
138147
if (writeNestedProperties) {
139148

@@ -189,14 +198,22 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
189198

190199
if (property.isAnnotationPresent(Mapping.class)) {
191200

192-
String mappingPath = property.getRequiredAnnotation(Mapping.class).mappingPath();
193-
if (!StringUtils.isEmpty(mappingPath)) {
201+
Mapping mapping = property.getRequiredAnnotation(Mapping.class);
202+
203+
if (mapping.enabled()) {
204+
String mappingPath = mapping.mappingPath();
194205

195-
ClassPathResource mappings = new ClassPathResource(mappingPath);
196-
if (mappings.exists()) {
197-
builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON);
198-
return;
206+
if (StringUtils.hasText(mappingPath)) {
207+
208+
ClassPathResource mappings = new ClassPathResource(mappingPath);
209+
if (mappings.exists()) {
210+
builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON);
211+
return;
212+
}
199213
}
214+
} else {
215+
applyDisabledPropertyMapping(builder, property);
216+
return;
200217
}
201218
}
202219

@@ -317,9 +334,29 @@ private void applyCompletionFieldMapping(XContentBuilder builder, ElasticsearchP
317334

318335
private void applyDefaultIdFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property)
319336
throws IOException {
337+
builder.startObject(property.getFieldName()) //
338+
.field(FIELD_PARAM_TYPE, TYPE_VALUE_KEYWORD) //
339+
.field(FIELD_INDEX, true) //
340+
.endObject(); //
341+
}
342+
343+
private void applyDisabledPropertyMapping(XContentBuilder builder, ElasticsearchPersistentProperty property)
344+
throws IOException {
320345

321-
builder.startObject(property.getFieldName()).field(FIELD_PARAM_TYPE, TYPE_VALUE_KEYWORD).field(FIELD_INDEX, true)
322-
.endObject();
346+
try {
347+
Field field = property.getRequiredAnnotation(Field.class);
348+
349+
if (field.type() != FieldType.Object) {
350+
throw new IllegalArgumentException("Field type must be 'object");
351+
}
352+
353+
builder.startObject(property.getFieldName()) //
354+
.field(FIELD_PARAM_TYPE, field.type().name().toLowerCase()) //
355+
.field(MAPPING_ENABLED, false) //
356+
.endObject(); //
357+
} catch (Exception e) {
358+
throw new MappingException("Could not write enabled: false mapping for " + property.getFieldName(), e);
359+
}
323360
}
324361

325362
/**

Diff for: src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java

+37-44
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import lombok.Setter;
3131

3232
import java.lang.Integer;
33+
import java.lang.Object;
3334
import java.math.BigDecimal;
3435
import java.util.Collection;
3536
import java.util.Collections;
@@ -268,9 +269,26 @@ void shouldWriteWildcardFieldMapping() {
268269
indexOps.putMapping();
269270
}
270271

271-
/**
272-
* @author Xiao Yu
273-
*/
272+
@Test // #1370
273+
@DisplayName("should write mapping for disabled entity")
274+
void shouldWriteMappingForDisabledEntity() {
275+
276+
IndexOperations indexOps = operations.indexOps(DisabledMappingEntity.class);
277+
indexOps.create();
278+
indexOps.putMapping();
279+
indexOps.delete();
280+
}
281+
282+
@Test // #1370
283+
@DisplayName("should write mapping for disabled property")
284+
void shouldWriteMappingForDisabledProperty() {
285+
286+
IndexOperations indexOps = operations.indexOps(DisabledMappingProperty.class);
287+
indexOps.create();
288+
indexOps.putMapping();
289+
indexOps.delete();
290+
}
291+
274292
@Setter
275293
@Getter
276294
@NoArgsConstructor
@@ -284,9 +302,6 @@ static class IgnoreAboveEntity {
284302
@Field(type = FieldType.Keyword, ignoreAbove = 10) private String message;
285303
}
286304

287-
/**
288-
* @author Peter-Josef Meisch
289-
*/
290305
static class FieldNameEntity {
291306

292307
@Document(indexName = "fieldname-index")
@@ -351,11 +366,6 @@ static class MultiFieldEntity {
351366
}
352367
}
353368

354-
/**
355-
* @author Rizwan Idrees
356-
* @author Mohsin Husen
357-
* @author Nordine Bittich
358-
*/
359369
@Setter
360370
@Getter
361371
@NoArgsConstructor
@@ -373,10 +383,6 @@ static class Book {
373383
searchAnalyzer = "standard") }) private String description;
374384
}
375385

376-
/**
377-
* @author Stuart Stevenson
378-
* @author Mohsin Husen
379-
*/
380386
@Data
381387
@Document(indexName = "test-index-simple-recursive-mapping-builder", replicas = 0, refreshInterval = "-1")
382388
static class SimpleRecursiveEntity {
@@ -386,9 +392,6 @@ static class SimpleRecursiveEntity {
386392
ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject;
387393
}
388394

389-
/**
390-
* @author Sascha Woo
391-
*/
392395
@Setter
393396
@Getter
394397
@NoArgsConstructor
@@ -406,9 +409,6 @@ static class CopyToEntity {
406409
@Field(type = FieldType.Keyword) private String name;
407410
}
408411

409-
/**
410-
* @author Sascha Woo
411-
*/
412412
@Setter
413413
@Getter
414414
@NoArgsConstructor
@@ -426,10 +426,6 @@ static class NormalizerEntity {
426426
type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) private String description;
427427
}
428428

429-
/**
430-
* @author Rizwan Idrees
431-
* @author Mohsin Husen
432-
*/
433429
static class Author {
434430

435431
@Nullable private String id;
@@ -454,9 +450,6 @@ public void setName(String name) {
454450
}
455451
}
456452

457-
/**
458-
* @author Kevin Leturc
459-
*/
460453
@Document(indexName = "test-index-sample-inherited-mapping-builder", replicas = 0, refreshInterval = "-1")
461454
static class SampleInheritedEntity extends AbstractInheritedEntity {
462455

@@ -472,9 +465,6 @@ public void setMessage(String message) {
472465
}
473466
}
474467

475-
/**
476-
* @author Kevin Leturc
477-
*/
478468
static class SampleInheritedEntityBuilder {
479469

480470
private final SampleInheritedEntity result;
@@ -506,10 +496,6 @@ public IndexQuery buildIndex() {
506496
}
507497
}
508498

509-
/**
510-
* @author Artur Konczak
511-
* @author Mohsin Husen
512-
*/
513499
@Setter
514500
@Getter
515501
@NoArgsConstructor
@@ -525,9 +511,6 @@ static class StockPrice {
525511
@Field(type = FieldType.Double) private BigDecimal price;
526512
}
527513

528-
/**
529-
* @author Kevin Letur
530-
*/
531514
static class AbstractInheritedEntity {
532515

533516
@Nullable @Id private String id;
@@ -580,19 +563,13 @@ static class GeoEntity {
580563
orientation = GeoShapeField.Orientation.clockwise) private String shape2;
581564
}
582565

583-
/**
584-
* Created by akonczak on 21/08/2016.
585-
*/
586566
@Document(indexName = "test-index-user-mapping-builder")
587567
static class User {
588568
@Nullable @Id private String id;
589569

590570
@Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set<Group> groups = new HashSet<>();
591571
}
592572

593-
/**
594-
* Created by akonczak on 21/08/2016.
595-
*/
596573
@Document(indexName = "test-index-group-mapping-builder")
597574
static class Group {
598575

@@ -662,4 +639,20 @@ static class WildcardEntity {
662639
@Nullable @Field(type = Wildcard) private String wildcardWithoutParams;
663640
@Nullable @Field(type = Wildcard, nullValue = "WILD", ignoreAbove = 42) private String wildcardWithParams;
664641
}
642+
643+
@Data
644+
@Document(indexName = "disabled-entity-mapping")
645+
@Mapping(enabled = false)
646+
static class DisabledMappingEntity {
647+
@Id private String id;
648+
@Field(type = Text) private String text;
649+
}
650+
651+
@Data
652+
@Document(indexName = "disabled-property-mapping")
653+
static class DisabledMappingProperty {
654+
@Id private String id;
655+
@Field(type = Text) private String text;
656+
@Mapping(enabled = false) @Field(type = Object) private Object object;
657+
}
665658
}

0 commit comments

Comments
 (0)