Dataes 716 - Add value mapping to the ElasticsearchMappingConverter.
Original PR: #366
This commit is contained in:
committed by
GitHub
parent
d2b7df87f4
commit
a68c6ba5d7
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* https://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.core;
|
||||
|
||||
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
|
||||
/**
|
||||
* Tests for the mapping of {@link CriteriaQuery} by a
|
||||
* {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. In the same package as
|
||||
* {@link CriteriaQueryProcessor} as this is needed to get the String represenation to assert.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
public class CriteriaQueryMappingTests {
|
||||
|
||||
MappingElasticsearchConverter mappingElasticsearchConverter;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
|
||||
mappingContext.setInitialEntitySet(Collections.singleton(Person.class));
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
mappingElasticsearchConverter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService());
|
||||
mappingElasticsearchConverter.afterPropertiesSet();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException {
|
||||
|
||||
// use POJO properties and types in the query building
|
||||
CriteriaQuery criteriaQuery = new CriteriaQuery(
|
||||
new Criteria("birthDate").between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28)));
|
||||
|
||||
// mapped field name and converted parameter
|
||||
String expected = '{' + //
|
||||
" \"bool\" : {" + //
|
||||
" \"should\" : [" + //
|
||||
" {" + //
|
||||
" \"range\" : {" + //
|
||||
" \"birth-date\" : {" + //
|
||||
" \"from\" : \"09.11.1989\"," + //
|
||||
" \"to\" : \"09.11.1990\"," + //
|
||||
" \"include_lower\" : true," + //
|
||||
" \"include_upper\" : true" + //
|
||||
" }" + //
|
||||
" }" + //
|
||||
" }," + //
|
||||
" {" + //
|
||||
" \"query_string\" : {" + //
|
||||
" \"query\" : \"28.12.2019\"," + //
|
||||
" \"fields\" : [" + //
|
||||
" \"birth-date^1.0\"" + //
|
||||
" ]" + //
|
||||
" }" + //
|
||||
" }" + //
|
||||
" ]" + //
|
||||
" }" + //
|
||||
'}'; //
|
||||
|
||||
mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class);
|
||||
String queryString = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()).toString();
|
||||
|
||||
assertEquals(expected, queryString, false);
|
||||
}
|
||||
|
||||
static class Person {
|
||||
@Id String id;
|
||||
@Field(name = "first-name") String firstName;
|
||||
@Field(name = "last-name") String lastName;
|
||||
@Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom,
|
||||
pattern = "dd.MM.yyyy") LocalDate birthDate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
class ElasticsearchDateConverterTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(DateFormat.class)
|
||||
void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) {
|
||||
|
||||
if (dateFormat == DateFormat.none) {
|
||||
return;
|
||||
}
|
||||
String pattern = (dateFormat != DateFormat.custom) ? dateFormat.name() : "dd.MM.yyyy";
|
||||
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(pattern);
|
||||
|
||||
assertThat(converter).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldConvertToString() {
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date);
|
||||
|
||||
String formatted = converter.format(localDate);
|
||||
|
||||
assertThat(formatted).isEqualTo("20191227");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldParseFromString() {
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date);
|
||||
|
||||
LocalDate parsed = converter.parse("20191227", LocalDate.class);
|
||||
|
||||
assertThat(parsed).isEqualTo(localDate);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.elasticsearch.core.convert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@@ -26,16 +27,17 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
@@ -47,10 +49,15 @@ import org.springframework.data.annotation.Transient;
|
||||
import org.springframework.data.annotation.TypeAlias;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.GeoPointField;
|
||||
import org.springframework.data.elasticsearch.core.document.Document;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Point;
|
||||
@@ -294,7 +301,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
public void writesNestedEntity() {
|
||||
|
||||
Person person = new Person();
|
||||
person.birthdate = new Date();
|
||||
person.birthDate = LocalDate.now();
|
||||
person.gender = Gender.MAN;
|
||||
person.address = observatoryRoad;
|
||||
|
||||
@@ -574,6 +581,45 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
assertThat(target.address).isEqualTo(bigBunsCafe);
|
||||
}
|
||||
|
||||
@Test // DATAES-716
|
||||
void shouldWriteLocalDate() throws JSONException {
|
||||
Person person = new Person();
|
||||
person.id = "4711";
|
||||
person.firstName = "John";
|
||||
person.lastName = "Doe";
|
||||
person.birthDate = LocalDate.of(2000, 8, 22);
|
||||
person.gender = Gender.MAN;
|
||||
|
||||
String expected = '{' + //
|
||||
" \"id\": \"4711\"," + //
|
||||
" \"first-name\": \"John\"," + //
|
||||
" \"last-name\": \"Doe\"," + //
|
||||
" \"birth-date\": \"22.08.2000\"," + //
|
||||
" \"gender\": \"MAN\"" + //
|
||||
'}';
|
||||
Document document = Document.create();
|
||||
mappingElasticsearchConverter.write(person, document);
|
||||
String json = document.toJson();
|
||||
|
||||
assertEquals(expected, json, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReadLocalDate() {
|
||||
Document document = Document.create();
|
||||
document.put("id", "4711");
|
||||
document.put("first-name", "John");
|
||||
document.put("last-name", "Doe");
|
||||
document.put("birth-date", "22.08.2000");
|
||||
document.put("gender", "MAN");
|
||||
|
||||
Person person = mappingElasticsearchConverter.read(Person.class, document);
|
||||
|
||||
assertThat(person.getId()).isEqualTo("4711");
|
||||
assertThat(person.getBirthDate()).isEqualTo(LocalDate.of(2000, 8, 22));
|
||||
assertThat(person.getGender()).isEqualTo(Gender.MAN);
|
||||
}
|
||||
|
||||
private String pointTemplate(String name, Point point) {
|
||||
return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY());
|
||||
}
|
||||
@@ -598,7 +644,10 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
|
||||
@Id String id;
|
||||
String name;
|
||||
Date birthdate;
|
||||
@Field(name = "first-name") String firstName;
|
||||
@Field(name = "last-name") String lastName;
|
||||
@Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom,
|
||||
pattern = "dd.MM.yyyy") LocalDate birthDate;
|
||||
Gender gender;
|
||||
Address address;
|
||||
|
||||
@@ -759,5 +808,4 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
|
||||
@GeoPointField private double[] pointD;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.lang.Boolean;
|
||||
import java.lang.Double;
|
||||
import java.lang.Integer;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
@@ -957,7 +958,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
@Field(copyTo = { "foo", "bar" }) private String copyTo;
|
||||
@Field(ignoreAbove = 42) private String ignoreAbove;
|
||||
@Field(type = FieldType.Integer) private String type;
|
||||
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private String date;
|
||||
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private LocalDate date;
|
||||
@Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers;
|
||||
@Field(type = Keyword, docValues = true) private String docValuesTrue;
|
||||
@Field(type = Keyword, docValues = false) private String docValuesFalse;
|
||||
|
||||
@@ -17,8 +17,14 @@ package org.springframework.data.elasticsearch.core.mapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.Score;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
|
||||
@@ -62,6 +68,47 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
assertThat(persistentProperty.getFieldName()).isEqualTo("by-value");
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
void shouldSetPropertyConverters() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("date");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isFalse();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
|
||||
persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateTime");
|
||||
assertThat(persistentProperty.hasPropertyConverter()).isTrue();
|
||||
assertThat(persistentProperty.getPropertyConverter()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
void shouldConvertFromLocalDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
LocalDate localDate = LocalDate.of(2019, 12, 27);
|
||||
|
||||
String converted = persistentProperty.getPropertyConverter().write(localDate);
|
||||
|
||||
assertThat(converted).isEqualTo("27.12.2019");
|
||||
}
|
||||
|
||||
@Test
|
||||
// DATAES-716
|
||||
void shouldConvertToLocalDate() {
|
||||
SimpleElasticsearchPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class);
|
||||
ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate");
|
||||
|
||||
Object converted = persistentProperty.getPropertyConverter().read("27.12.2019");
|
||||
|
||||
assertThat(converted).isInstanceOf(LocalDate.class);
|
||||
assertThat(converted).isEqualTo(LocalDate.of(2019, 12, 27));
|
||||
}
|
||||
|
||||
static class InvalidScoreProperty {
|
||||
@Score String scoreProperty;
|
||||
}
|
||||
@@ -73,4 +120,10 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
static class FieldValueProperty {
|
||||
@Field(value = "by-value") String fieldProperty;
|
||||
}
|
||||
|
||||
static class DatesProperty {
|
||||
@Field(type = FieldType.Date, format = DateFormat.basic_date) Date date;
|
||||
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.yyyy") LocalDate localDate;
|
||||
@Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user