From 21577aab00380a4a519c85b7c6ba17faebe88ea1 Mon Sep 17 00:00:00 2001 From: Jakub Vavrik Date: Mon, 7 Oct 2013 10:08:05 +0200 Subject: [PATCH] added format and pattern support for date fieldtype + fixed nullpointer when TransportClientFactoryBean configuration is java config only. --- .../elasticsearch/annotations/DateFormat.java | 17 +++++ .../data/elasticsearch/annotations/Field.java | 5 ++ .../client/TransportClientFactoryBean.java | 7 +- .../elasticsearch/core/MappingBuilder.java | 5 ++ .../SampleDateMappingEntity.java | 73 +++++++++++++++++++ .../SimpleElasticsearchDateMappingTest.java | 26 +++++++ 6 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/SampleDateMappingEntity.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java new file mode 100644 index 000000000..3ee43aa2c --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java @@ -0,0 +1,17 @@ +package org.springframework.data.elasticsearch.annotations; + +/** + * @author Jakub Vavrik + * + * Values based on reference doc - http://www.elasticsearch.org/guide/reference/mapping/date-format/ + */ +public enum DateFormat { + none, custom, basic_date, basic_date_time, basic_date_time_no_millis, basic_ordinal_date, basic_ordinal_date_time, + basic_ordinal_date_time_no_millis, basic_time, basic_time_no_millis, basic_t_time, basic_t_time_no_millis, + basic_week_date, basic_week_date_time, basic_week_date_time_no_millis, date, date_hour, date_hour_minute, + date_hour_minute_second, date_hour_minute_second_fraction, date_hour_minute_second_millis, date_optional_time, + date_time, date_time_no_millis, hour, hour_minute, hour_minute_second, hour_minute_second_fraction, + hour_minute_second_millis, ordinal_date, ordinal_date_time, ordinal_date_time_no_millis, time, time_no_millis, + t_time, t_time_no_millis, week_date, week_date_time, weekDateTimeNoMillis, week_year, weekyearWeek, + weekyearWeekDay, year, year_month, year_month_day +} 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 d52675067..a4cf1adc5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java @@ -22,6 +22,7 @@ import java.lang.annotation.*; * @author Mohsin Husen * @author Artur Konczak * @author Jonathan Yan + * @author Jakub Vavrik */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @@ -32,6 +33,10 @@ public @interface Field { FieldIndex index() default FieldIndex.analyzed; + DateFormat format() default DateFormat.none; + + String pattern() default ""; + boolean store() default false; String searchAnalyzer() default ""; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java index 9c78e45de..bd3294f26 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java @@ -35,6 +35,7 @@ import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilde * * @author Rizwan Idrees * @author Mohsin Husen + * @author Jakub Vavrik */ public class TransportClientFactoryBean implements FactoryBean, InitializingBean, DisposableBean { @@ -43,9 +44,9 @@ public class TransportClientFactoryBean implements FactoryBean, private String clusterNodes; private String clusterName; private Boolean clientTransportSniff; - private Boolean clientIgnoreClusterName; - private String clientPingTimeout; - private String clientNodesSamplerInterval; + private Boolean clientIgnoreClusterName = Boolean.FALSE; + private String clientPingTimeout = "5s"; + private String clientNodesSamplerInterval = "5s"; private TransportClient client; private Properties properties; static final String COLON = ":"; 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 cc6de328f..77ee015ea 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java @@ -41,6 +41,7 @@ class MappingBuilder { public static final String FIELD_STORE = "store"; public static final String FIELD_TYPE = "type"; public static final String FIELD_INDEX = "index"; + public static final String FIELD_FORMAT = "format"; public static final String FIELD_SEARCH_ANALYZER = "search_analyzer"; public static final String FIELD_INDEX_ANALYZER = "index_analyzer"; public static final String FIELD_PROPERTIES = "properties"; @@ -125,6 +126,10 @@ class MappingBuilder { xContentBuilder.field(FIELD_STORE, fieldAnnotation.store()); if (FieldType.Auto != fieldAnnotation.type()) { xContentBuilder.field(FIELD_TYPE, fieldAnnotation.type().name().toLowerCase()); + if (FieldType.Date == fieldAnnotation.type() && DateFormat.none != fieldAnnotation.format()) { + xContentBuilder.field(FIELD_FORMAT, DateFormat.custom == fieldAnnotation.format() + ? fieldAnnotation.pattern() : fieldAnnotation.format()); + } } if (FieldIndex.not_analyzed == fieldAnnotation.index()) { xContentBuilder.field(FIELD_INDEX, fieldAnnotation.index().name().toLowerCase()); diff --git a/src/test/java/org/springframework/data/elasticsearch/SampleDateMappingEntity.java b/src/test/java/org/springframework/data/elasticsearch/SampleDateMappingEntity.java new file mode 100644 index 000000000..3d7ca3f29 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/SampleDateMappingEntity.java @@ -0,0 +1,73 @@ +package org.springframework.data.elasticsearch; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.DateFormat; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; + +import java.util.Date; + +import static org.springframework.data.elasticsearch.annotations.FieldIndex.not_analyzed; +import static org.springframework.data.elasticsearch.annotations.FieldType.String; +import static org.springframework.data.elasticsearch.annotations.FieldType.Date; + +/** + * @author Jakub Vavrik + */ +@Document(indexName = "test-datemapping", type = "mapping", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1") +public class SampleDateMappingEntity { + @Id + private String id; + + @Field(type = String, index = not_analyzed, store = true, searchAnalyzer = "standard", indexAnalyzer = "standard") + private String message; + + @Field(type = Date, format = DateFormat.custom, pattern = "dd.MM.yyyy hh:mm") + private Date customFormatDate; + + @Field(type = Date) + private Date defaultFormatDate; + + @Field(type = Date, format = DateFormat.basic_date) + private Date basicFormatDate; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Date getCustomFormatDate() { + return customFormatDate; + } + + public void setCustomFormatDate(Date customFormatDate) { + this.customFormatDate = customFormatDate; + } + + public Date getDefaultFormatDate() { + return defaultFormatDate; + } + + public void setDefaultFormatDate(Date defaultFormatDate) { + this.defaultFormatDate = defaultFormatDate; + } + + public Date getBasicFormatDate() { + return basicFormatDate; + } + + public void setBasicFormatDate(Date basicFormatDate) { + this.basicFormatDate = basicFormatDate; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTest.java b/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTest.java new file mode 100644 index 000000000..cc31c0476 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTest.java @@ -0,0 +1,26 @@ +package org.springframework.data.elasticsearch.core; + +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.data.elasticsearch.SampleDateMappingEntity; + +import java.beans.IntrospectionException; +import java.io.IOException; + +/** + * @author Jakub Vavrik + */ +public class SimpleElasticsearchDateMappingTest { + private static final String EXPECTED_MAPPING = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true," + + "\"type\":\"string\",\"index\":\"not_analyzed\",\"search_analyzer\":\"standard\",\"index_analyzer\"" + + ":\"standard\"},\"customFormatDate\":{\"store\":false,\"type\":\"date\",\"format\":\"dd.MM.yyyy hh:mm\"}," + + "\"defaultFormatDate\":{\"store\":false,\"type\":\"date\"},\"basicFormatDate\":{\"store\":false,\"" + + "type\":\"date\",\"format\":\"basic_date\"}}}}"; + + @Test + public void testCorrectDateMappings() throws NoSuchFieldException, IntrospectionException, IOException { + XContentBuilder xContentBuilder = MappingBuilder.buildMapping(SampleDateMappingEntity.class, "mapping", "id"); + Assert.assertEquals(EXPECTED_MAPPING, xContentBuilder.string()); + } +}