From e6fbc37550ac6c6ffa26fea8b480be1ede64908e Mon Sep 17 00:00:00 2001 From: xhaggi Date: Tue, 23 Oct 2018 09:25:29 +0200 Subject: [PATCH] DATAES-492 - Add missing normalizer property to @Field and @InnerField. Original pull request: #222 --- .../data/elasticsearch/annotations/Field.java | 4 +- .../elasticsearch/annotations/InnerField.java | 8 ++- .../elasticsearch/core/MappingBuilder.java | 7 +++ .../core/MappingBuilderTests.java | 22 ++++++++ .../entities/NormalizerEntity.java | 52 +++++++++++++++++++ .../resources/settings/test-normalizer.json | 13 +++++ 6 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/entities/NormalizerEntity.java create mode 100644 src/test/resources/settings/test-normalizer.json diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java index 2b48eedfb..18a5a3fe3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,8 @@ public @interface Field { String analyzer() default ""; + String normalizer() default ""; + String[] ignoreFields() default {}; boolean includeInParent() default false; diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java index 2a0a95def..1f5bdfc30 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,9 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * + * @author Artur Konczak + * @author Mohsin Husen + * @author Sascha Woo */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @@ -44,4 +46,6 @@ public @interface InnerField { String searchAnalyzer() default ""; String analyzer() default ""; + + String normalizer() default ""; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java index 27fb73546..6658bad44 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java @@ -63,6 +63,7 @@ class MappingBuilder { public static final String FIELD_FORMAT = "format"; public static final String FIELD_SEARCH_ANALYZER = "search_analyzer"; public static final String FIELD_INDEX_ANALYZER = "analyzer"; + public static final String FIELD_NORMALIZER = "normalizer"; public static final String FIELD_PROPERTIES = "properties"; public static final String FIELD_PARENT = "_parent"; @@ -269,6 +270,7 @@ class MappingBuilder { String datePattern = null; String analyzer = null; String searchAnalyzer = null; + String normalizer = null; if (annotation instanceof Field) { // @Field @@ -281,6 +283,7 @@ class MappingBuilder { datePattern = fieldAnnotation.pattern(); analyzer = fieldAnnotation.analyzer(); searchAnalyzer = fieldAnnotation.searchAnalyzer(); + normalizer = fieldAnnotation.normalizer(); } else if (annotation instanceof InnerField) { // @InnerField InnerField fieldAnnotation = (InnerField) annotation; @@ -292,6 +295,7 @@ class MappingBuilder { datePattern = fieldAnnotation.pattern(); analyzer = fieldAnnotation.analyzer(); searchAnalyzer = fieldAnnotation.searchAnalyzer(); + normalizer = fieldAnnotation.normalizer(); } else { throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField"); } @@ -318,6 +322,9 @@ class MappingBuilder { if (!StringUtils.isEmpty(searchAnalyzer)) { builder.field(FIELD_SEARCH_ANALYZER, searchAnalyzer); } + if (!StringUtils.isEmpty(normalizer)) { + builder.field(FIELD_NORMALIZER, normalizer); + } } protected static boolean isEntity(java.lang.reflect.Field field) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java index ebd1754d5..3ed606667 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java @@ -45,6 +45,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Mohsin Husen * @author Keivn Leturc * @author Nordine Bittich + * @author Sascha Woo */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:elasticsearch-template-test.xml") @@ -215,4 +216,25 @@ public class MappingBuilderTests { assertThat(descriptionMapping.get("type"), equalTo("text")); assertThat(descriptionMapping.get("analyzer"), equalTo("whitespace")); } + + @Test // DATAES-492 + public void shouldUseKeywordNormalizer() throws IOException { + + // given + elasticsearchTemplate.deleteIndex(NormalizerEntity.class); + elasticsearchTemplate.createIndex(NormalizerEntity.class); + elasticsearchTemplate.putMapping(NormalizerEntity.class); + + // when + Map mapping = elasticsearchTemplate.getMapping(NormalizerEntity.class); + Map properties = (Map) mapping.get("properties"); + Map fieldName = (Map) properties.get("name"); + Map fieldDescriptionLowerCase = (Map) ((Map) ((Map) properties.get("description")).get("fields")).get("lower_case"); + + // then + assertThat(fieldName.get("type"), equalTo("keyword")); + assertThat(fieldName.get("normalizer"), equalTo("lower_case_normalizer")); + assertThat(fieldDescriptionLowerCase.get("type"), equalTo("keyword")); + assertThat(fieldDescriptionLowerCase.get("normalizer"), equalTo("lower_case_normalizer")); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/entities/NormalizerEntity.java b/src/test/java/org/springframework/data/elasticsearch/entities/NormalizerEntity.java new file mode 100644 index 000000000..9cf75c074 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/entities/NormalizerEntity.java @@ -0,0 +1,52 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.elasticsearch.entities; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.annotations.Setting; + +/** + * @author Sascha Woo + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Document(indexName = "test-index-normalizer", type = "test", shards = 1, replicas = 0, refreshInterval = "-1") +@Setting(settingPath = "/settings/test-normalizer.json") +public class NormalizerEntity { + + @Id private String id; + + @Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer") + private String name; + + @MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case", + type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) + private String description; +} diff --git a/src/test/resources/settings/test-normalizer.json b/src/test/resources/settings/test-normalizer.json new file mode 100644 index 000000000..5892dd8c3 --- /dev/null +++ b/src/test/resources/settings/test-normalizer.json @@ -0,0 +1,13 @@ +{ + "index": { + "analysis": { + "normalizer": { + "lower_case_normalizer": { + "type": "custom", + "char_filter": [], + "filter": [ "lowercase" ] + } + } + } + } +} \ No newline at end of file