1
0
mirror of synced 2026-05-27 06:33:18 +00:00

Compare commits

...

16 Commits

Author SHA1 Message Date
Mark Paluch b5e7c3d012 Release version 5.0.12 (2022.0.12).
See #2735
2023-11-17 10:57:14 +01:00
Mark Paluch 2b8fbc18a2 Prepare 5.0.12 (2022.0.12).
See #2735
2023-11-17 10:57:00 +01:00
Peter-Josef Meisch f1f73a2992 Upgrade dependency of deprecated Elasticsearch client to 7.17.15.
Original Pull Request #2768
Closes #2764
2023-11-15 20:54:30 +01:00
Peter-Josef Meisch 50d606bfb8 Use routing info on delete operations.
Original Pull Request #2755
Closes #2754

(cherry picked from commit 9abcacb2e9)
(cherry picked from commit 64cf9566d9)
2023-11-06 22:17:30 +01:00
Peter-Josef Meisch 44b0ef0dac Fix reactive native sort.
Original Pull Request #2746
Closes #2745

(cherry picked from commit 73fe0869e6)
(cherry picked from commit 2c857178f4)
2023-10-23 22:07:55 +02:00
Peter-Josef Meisch 69329bc62d Fix field parameters in search request creation.
Original Pull Request #2739
Closes #2727

(cherry picked from commit f087d5aac3)
2023-10-14 11:52:45 +02:00
Mark Paluch aaaa18ec4c After release cleanups.
See #2698
2023-10-13 11:44:29 +02:00
Mark Paluch e9c2961133 Prepare next development iteration.
See #2698
2023-10-13 11:44:28 +02:00
Mark Paluch 08ed5b724d Release version 5.0.11 (2022.0.11).
See #2698
2023-10-13 11:41:41 +02:00
Mark Paluch 12b869e9dd Prepare 5.0.11 (2022.0.11).
See #2698
2023-10-13 11:41:28 +02:00
Peter-Josef Meisch d35dd313b1 Upgrade to Elasticsearch 7.17.14.
Original Pull Request #2733
2023-10-13 08:41:05 +02:00
John Blum f65d557689 Upgrade to Maven Wrapper 3.9.5.
See #2716
2023-10-04 18:24:26 -07:00
John Blum 1c4332dd12 Update CI properties.
See #2698
2023-10-04 17:47:35 -07:00
Peter-Josef Meisch b21bd796f6 Fix converting of Range<?> in Lists.
Original Pull Request #2707
Closes #2706

(cherry picked from commit 3330d65edf)
(cherry picked from commit d26d01bab1)
2023-09-23 13:21:50 +02:00
Mark Paluch 16eefb6f60 After release cleanups.
See #2673
2023-09-15 10:20:52 +02:00
Mark Paluch 7ebc4ee13a Prepare next development iteration.
See #2673
2023-09-15 10:20:50 +02:00
19 changed files with 298 additions and 66 deletions
+2 -2
View File
@@ -1,3 +1,3 @@
#Mon Aug 14 07:45:53 EDT 2023
#Wed Oct 04 18:24:26 PDT 2023
wrapperUrl=https\://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.4/apache-maven-3.9.4-bin.zip
distributionUrl=https\://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
+4 -4
View File
@@ -7,15 +7,15 @@ docker.java.main.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/ecli
docker.java.next.image=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.next.tag}
# Supported versions of MongoDB
docker.mongodb.4.4.version=4.4.23
docker.mongodb.5.0.version=5.0.19
docker.mongodb.6.0.version=6.0.8
docker.mongodb.4.4.version=4.4.25
docker.mongodb.5.0.version=5.0.21
docker.mongodb.6.0.version=6.0.10
# Supported versions of Redis
docker.redis.6.version=6.2.13
# Supported versions of Cassandra
docker.cassandra.3.version=3.11.15
docker.cassandra.3.version=3.11.16
# Docker environment settings
docker.java.inside.basic=-v $HOME:/tmp/jenkins-home
+4 -4
View File
@@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>5.0.10</version>
<version>5.0.12</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>3.0.10</version>
<version>3.0.12</version>
</parent>
<name>Spring Data Elasticsearch</name>
@@ -18,10 +18,10 @@
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties>
<springdata.commons>3.0.10</springdata.commons>
<springdata.commons>3.0.12</springdata.commons>
<!-- version of the RestHighLevelClient -->
<elasticsearch-rhlc>7.17.13</elasticsearch-rhlc>
<elasticsearch-rhlc>7.17.15</elasticsearch-rhlc>
<!-- version of the new ElasticsearchClient -->
<elasticsearch-java>8.5.3</elasticsearch-java>
@@ -30,6 +30,7 @@ import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.RuntimeField;
import co.elastic.clients.elasticsearch._types.mapping.RuntimeFieldType;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch._types.query_dsl.FieldAndFormat;
import co.elastic.clients.elasticsearch._types.query_dsl.Like;
import co.elastic.clients.elasticsearch.cluster.HealthRequest;
import co.elastic.clients.elasticsearch.core.*;
@@ -1050,10 +1051,9 @@ class RequestConverter {
}
if (!isEmpty(query.getFields())) {
bb.fields(fb -> {
query.getFields().forEach(fb::field);
return fb;
});
var fieldAndFormats = query.getFields().stream()
.map(field -> FieldAndFormat.of(b -> b.field(field))).toList();
bb.fields(fieldAndFormats);
}
if (!isEmpty(query.getStoredFields())) {
@@ -1169,10 +1169,9 @@ class RequestConverter {
builder.source(getSourceConfig(query));
if (!isEmpty(query.getFields())) {
builder.fields(fb -> {
query.getFields().forEach(fb::field);
return fb;
});
var fieldAndFormats = query.getFields().stream()
.map(field -> FieldAndFormat.of(b -> b.field(field))).toList();
builder.fields(fieldAndFormats);
}
if (!isEmpty(query.getStoredFields())) {
@@ -1193,6 +1192,13 @@ class RequestConverter {
builder.searchType(searchType(query.getSearchType()));
addHighlight(query, builder);
if (query instanceof NativeQuery) {
prepareNativeSearch((NativeQuery) query, builder);
}
// query.getSort() must be checked after prepareNativeSearch as this already might hav a sort set that must have
// higher priority
if (query.getSort() != null) {
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
@@ -1201,12 +1207,6 @@ class RequestConverter {
}
}
addHighlight(query, builder);
if (query instanceof NativeQuery) {
prepareNativeSearch((NativeQuery) query, builder);
}
if (query.getTrackTotalHits() != null) {
// logic from the RHLC, choose between -1 and Integer.MAX_VALUE
int value = query.getTrackTotalHits() ? Integer.MAX_VALUE : -1;
@@ -658,6 +658,12 @@ abstract public class AbstractReactiveElasticsearchTemplate
public abstract Mono<String> getClusterVersion();
@Nullable
public String getEntityRouting(Object entity) {
return entityOperations.forEntity(entity, converter.getConversionService(), routingResolver)
.getRouting();
}
/**
* Value class to capture client independent information from a response to an index request.
*/
@@ -115,6 +115,17 @@ public interface ReactiveElasticsearchOperations extends ReactiveDocumentOperati
ReactiveClusterOperations cluster();
// region routing
/**
* gets the routing for an entity.
*
* @param entity the entity
* @return the routing, may be null if not set.
* @since 5.2
*/
@Nullable
String getEntityRouting(Object entity);
// region customizations
/**
* Returns a copy of this instance with the same configuration, but that uses a different {@link RoutingResolver} to
* obtain routing information.
@@ -32,9 +32,19 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
protected static final String LTE_FIELD = "lte";
protected static final String GT_FIELD = "gt";
protected static final String GTE_FIELD = "gte";
private final Class<?> genericType;
public AbstractRangePropertyValueConverter(PersistentProperty<?> property) {
/**
* @param property the property this convertrer belongs to
* @param genericType the generic type of the Range
*/
public AbstractRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
super(property);
this.genericType = genericType;
}
public Class<?> getGenericType() {
return genericType;
}
@Override
@@ -117,10 +127,6 @@ public abstract class AbstractRangePropertyValueConverter<T> extends AbstractPro
protected abstract String format(T value);
protected Class<?> getGenericType() {
return getProperty().getTypeInformation().getTypeArguments().get(0).getType();
}
protected abstract T parse(String value);
}
@@ -33,9 +33,9 @@ public class DateRangePropertyValueConverter extends AbstractRangePropertyValueC
private final List<ElasticsearchDateConverter> dateConverters;
public DateRangePropertyValueConverter(PersistentProperty<?> property,
List<ElasticsearchDateConverter> dateConverters) {
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
super(property);
super(property, genericType);
this.dateConverters = dateConverters;
}
@@ -23,8 +23,12 @@ import org.springframework.data.mapping.PersistentProperty;
*/
public class NumberRangePropertyValueConverter extends AbstractRangePropertyValueConverter<Number> {
public NumberRangePropertyValueConverter(PersistentProperty<?> property) {
super(property);
/**
* @param property the property this convertrer belongs to
* @param genericType the generic type of the Range
*/
public NumberRangePropertyValueConverter(PersistentProperty<?> property, Class<?> genericType) {
super(property, genericType);
}
@Override
@@ -34,9 +34,9 @@ public class TemporalRangePropertyValueConverter extends AbstractRangePropertyVa
private final List<ElasticsearchDateConverter> dateConverters;
public TemporalRangePropertyValueConverter(PersistentProperty<?> property,
List<ElasticsearchDateConverter> dateConverters) {
Class<?> genericType, List<ElasticsearchDateConverter> dateConverters) {
super(property);
super(property, genericType);
Assert.notEmpty(dateConverters, "dateConverters must not be empty.");
this.dateConverters = dateConverters;
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -54,6 +55,7 @@ import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.Property;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
@@ -158,6 +160,18 @@ public class SimpleElasticsearchPersistentProperty extends
return;
}
Supplier<Class<?>> getGenericType = () -> {
TypeInformation<?> typeInformation = getTypeInformation();
if (typeInformation.isCollectionLike()) {
// we have a collection of Range<?>
typeInformation = typeInformation.getComponentType();
}
Class<?> genericType = typeInformation.getTypeArguments().get(0).getType();
return genericType;
};
switch (field.type()) {
case Date:
case Date_Nanos: {
@@ -187,11 +201,11 @@ public class SimpleElasticsearchPersistentProperty extends
return;
}
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
var genericType = getGenericType.get();
if (TemporalAccessor.class.isAssignableFrom(genericType)) {
propertyValueConverter = new TemporalRangePropertyValueConverter(this, dateConverters);
propertyValueConverter = new TemporalRangePropertyValueConverter(this, genericType, dateConverters);
} else if (Date.class.isAssignableFrom(genericType)) {
propertyValueConverter = new DateRangePropertyValueConverter(this, dateConverters);
propertyValueConverter = new DateRangePropertyValueConverter(this, genericType, dateConverters);
} else {
LOGGER.warn(
String.format("Unsupported generic type '{%s' for date range property '%s'.", genericType, getName()));
@@ -206,7 +220,7 @@ public class SimpleElasticsearchPersistentProperty extends
return;
}
Class<?> genericType = getTypeInformation().getTypeArguments().get(0).getType();
var genericType = getGenericType.get();
if ((field.type() == FieldType.Integer_Range && !Integer.class.isAssignableFrom(genericType))
|| (field.type() == FieldType.Float_Range && !Float.class.isAssignableFrom(genericType))
|| (field.type() == FieldType.Long_Range && !Long.class.isAssignableFrom(genericType))
@@ -216,7 +230,7 @@ public class SimpleElasticsearchPersistentProperty extends
return;
}
propertyValueConverter = new NumberRangePropertyValueConverter(this);
propertyValueConverter = new NumberRangePropertyValueConverter(this, genericType);
break;
}
case Ip_Range: {
@@ -39,6 +39,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.BaseQuery;
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.util.StreamUtils;
import org.springframework.data.util.Streamable;
@@ -223,7 +224,7 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
Assert.notNull(id, "Cannot delete entity with id 'null'.");
doDelete(id, getIndexCoordinates());
doDelete(id, null, getIndexCoordinates());
}
@Override
@@ -231,7 +232,7 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
Assert.notNull(entity, "Cannot delete 'null' entity.");
doDelete(extractIdFromBean(entity), getIndexCoordinates());
doDelete(extractIdFromBean(entity), operations.getEntityRouting(entity), getIndexCoordinates());
}
@Override
@@ -271,10 +272,14 @@ public class SimpleElasticsearchRepository<T, ID> implements ElasticsearchReposi
deleteAllById(ids);
}
private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) {
private void doDelete(@Nullable ID id, @Nullable String routing, IndexCoordinates indexCoordinates) {
if (id != null) {
executeAndRefresh(operations -> operations.delete(stringIdRepresentation(id), indexCoordinates));
executeAndRefresh(operations -> {
var ops = routing != null ? operations.withRouting(RoutingResolver.just(routing)) : operations;
// noinspection DataFlowIssue
return ops.delete(stringIdRepresentation(id), indexCoordinates);
});
}
}
@@ -31,6 +31,7 @@ import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.routing.RoutingResolver;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.util.Assert;
@@ -196,7 +197,10 @@ public class SimpleReactiveElasticsearchRepository<T, ID> implements ReactiveEla
public Mono<Void> delete(T entity) {
Assert.notNull(entity, "Entity must not be null!");
return operations.delete(entity, entityInformation.getIndexCoordinates()) //
var routing = operations.getEntityRouting(entity);
var ops = routing != null ? operations.withRouting(RoutingResolver.just(routing)) : operations;
return ops.delete(entity, entityInformation.getIndexCoordinates()) //
.then(doRefresh());
}
+3 -1
View File
@@ -1,4 +1,4 @@
Spring Data Elasticsearch 5.0.10 (2022.0.10)
Spring Data Elasticsearch 5.0.12 (2022.0.12)
Copyright (c) [2013-2021] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -26,3 +26,5 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
@@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.client.elc.QueryBuilders.*;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
import co.elastic.clients.elasticsearch._types.aggregations.Buckets;
import co.elastic.clients.elasticsearch._types.aggregations.StringTermsAggregate;
@@ -27,10 +28,13 @@ import co.elastic.clients.elasticsearch.core.search.FieldCollapse;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.elasticsearch.ELCQueries;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.client.elc.Aggregation;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchAggregation;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
@@ -48,6 +52,51 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = ReactiveElasticsearchELCIntegrationTests.Config.class)
public class ReactiveElasticsearchELCIntegrationTests extends ReactiveElasticsearchIntegrationTests {
@Test // #2745
@DisplayName("should use sort defined in native unbounded query")
void shouldUseSortDefinedInNativeUnboundedQuery() {
var entity1 = randomEntity(null);
entity1.setRate(7);
var entity2 = randomEntity(null);
entity2.setRate(5);
var entity3 = randomEntity(null);
entity3.setRate(11);
operations.saveAll(List.of(entity1, entity2, entity3), SampleEntity.class).blockLast();
var query = NativeQuery.builder()
.withQuery(qb -> qb
.matchAll(m -> m))
.withSort(sob -> sob
.field(f -> f
.field("rate")
.order(SortOrder.Asc)))
.withPageable(Pageable.unpaged())
.build();
var rates = operations.search(query, SampleEntity.class)
.map(SearchHit::getContent)
.map(SampleEntity::getRate)
.collectList().block();
assertThat(rates).containsExactly(5, 7, 11);
query = NativeQuery.builder()
.withQuery(qb -> qb
.matchAll(m -> m))
.withSort(sob -> sob
.field(f -> f
.field("rate")
.order(SortOrder.Desc)))
.withPageable(Pageable.unpaged())
.build();
rates = operations.search(query, SampleEntity.class)
.map(SearchHit::getContent)
.map(SampleEntity::getRate)
.collectList().block();
assertThat(rates).containsExactly(11, 7, 5);
}
@Configuration
@Import({ ReactiveElasticsearchTemplateConfiguration.class })
static class Config {
@@ -96,7 +96,7 @@ import org.springframework.util.StringUtils;
@SpringIntegrationTest
public abstract class ReactiveElasticsearchIntegrationTests {
@Autowired private ReactiveElasticsearchOperations operations;
@Autowired protected ReactiveElasticsearchOperations operations;
@Autowired private IndexNameProvider indexNameProvider;
// region Setup
@@ -1165,7 +1165,7 @@ public abstract class ReactiveElasticsearchIntegrationTests {
// endregion
// region Helper functions
private SampleEntity randomEntity(String message) {
protected SampleEntity randomEntity(@Nullable String message) {
SampleEntity entity = new SampleEntity();
entity.setId(UUID.randomUUID().toString());
@@ -31,6 +31,7 @@ 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.Mapping;
import org.springframework.data.elasticsearch.annotations.ScriptedField;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
@@ -95,6 +96,88 @@ public abstract class RuntimeFieldsIntegrationTests {
assertThat(searchHits.getSearchHit(0).getId()).isEqualTo("1");
}
@Test // #2727
@DisplayName("should return runtime fields values")
void shouldReturnRuntimeFieldsValues() {
var entity = new SAREntity();
entity.setId("42");
entity.setValue(3);
operations.save(entity);
var runtimeField1 = getRuntimeField("scriptedValue1", 2);
var runtimeField2 = getRuntimeField("scriptedValue2", 3);
var query = CriteriaQuery.builder(Criteria.where("value").is(3)).build();
query.addRuntimeField(runtimeField1);
query.addRuntimeField(runtimeField2);
query.addSourceFilter(new FetchSourceFilterBuilder().withIncludes("*").build());
query.addFields("scriptedValue1", "scriptedValue2");
var searchHits = operations.search(query, SAREntity.class);
assertThat(searchHits.getTotalHits()).isEqualTo(1);
var foundEntity = searchHits.getSearchHit(0).getContent();
assertThat(foundEntity.value).isEqualTo(3);
assertThat(foundEntity.getScriptedValue1()).isEqualTo(6);
assertThat(foundEntity.getScriptedValue2()).isEqualTo(9);
}
@Document(indexName = "#{@indexNameProvider.indexName()}-sar")
public static class SAREntity {
@Nullable private String id;
@Field(type = FieldType.Integer)
@Nullable Integer value;
@ScriptedField
@Nullable Integer scriptedValue1;
@ScriptedField
@Nullable Integer scriptedValue2;
// getter and setter omitted
@Nullable
public String getId() {
return id;
}
public void setId(@Nullable String id) {
this.id = id;
}
@Nullable
public Integer getValue() {
return value;
}
public void setValue(@Nullable Integer value) {
this.value = value;
}
@Nullable
public Integer getScriptedValue1() {
return scriptedValue1;
}
public void setScriptedValue1(@Nullable Integer scriptedValue1) {
this.scriptedValue1 = scriptedValue1;
}
@Nullable
public Integer getScriptedValue2() {
return scriptedValue2;
}
public void setScriptedValue2(@Nullable Integer scriptedValue2) {
this.scriptedValue2 = scriptedValue2;
}
}
private static RuntimeField getRuntimeField(String fieldName, int factor) {
return new RuntimeField(
fieldName,
"long",
String.format("emit(doc['value'].size() > 0 ? doc['value'].value * %d : 0)", factor));
}
@Test // #2431
@DisplayName("should return value from runtime field defined in mapping")
void shouldReturnValueFromRuntimeFieldDefinedInMapping() {
@@ -960,19 +960,57 @@ public class MappingElasticsearchConverterUnitTests {
@Nested
class RangeTests {
static final String JSON = "{"
+ "\"_class\":\"org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity\","
+ "\"integerRange\":{\"gt\":\"1\",\"lt\":\"10\"}," //
+ "\"floatRange\":{\"gte\":\"1.2\",\"lte\":\"2.5\"}," //
+ "\"longRange\":{\"gt\":\"2\",\"lte\":\"5\"}," //
+ "\"doubleRange\":{\"gte\":\"3.2\",\"lt\":\"7.4\"}," //
+ "\"dateRange\":{\"gte\":\"1970-01-01T00:00:00.000Z\",\"lte\":\"1970-01-01T01:00:00.000Z\"}," //
+ "\"localDateRange\":{\"gte\":\"2021-07-06\"}," //
+ "\"localTimeRange\":{\"gte\":\"00:30:00.000\",\"lt\":\"02:30:00.000\"}," //
+ "\"localDateTimeRange\":{\"gt\":\"2021-01-01T00:30:00.000\",\"lt\":\"2021-01-01T02:30:00.000\"}," //
+ "\"offsetTimeRange\":{\"gte\":\"00:30:00.000+02:00\",\"lt\":\"02:30:00.000+02:00\"}," //
+ "\"zonedDateTimeRange\":{\"gte\":\"2021-01-01T00:30:00.000+02:00\",\"lte\":\"2021-01-01T00:30:00.000+02:00\"}," //
+ "\"nullRange\":null}";
static final String JSON = """
{
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$RangeTests$RangeEntity",
"integerRange": {
"gt": "1",
"lt": "10"
},
"floatRange": {
"gte": "1.2",
"lte": "2.5"
},
"longRange": {
"gt": "2",
"lte": "5"
},
"doubleRange": {
"gte": "3.2",
"lt": "7.4"
},
"dateRange": {
"gte": "1970-01-01T00:00:00.000Z",
"lte": "1970-01-01T01:00:00.000Z"
},
"localDateRange": {
"gte": "2021-07-06"
},
"localTimeRange": {
"gte": "00:30:00.000",
"lt": "02:30:00.000"
},
"localDateTimeRange": {
"gt": "2021-01-01T00:30:00.000",
"lt": "2021-01-01T02:30:00.000"
},
"offsetTimeRange": {
"gte": "00:30:00.000+02:00",
"lt": "02:30:00.000+02:00"
},
"zonedDateTimeRange": {
"gte": "2021-01-01T00:30:00.000+02:00",
"lte": "2021-01-01T00:30:00.000+02:00"
},
"nullRange": null,
"integerRangeList": [
{
"gte": "2",
"lte": "5"
}
]
}
""";
@Test
public void shouldReadRanges() throws JSONException {
@@ -1003,6 +1041,7 @@ public class MappingElasticsearchConverterUnitTests {
assertThat(e.getZonedDateTimeRange()).isEqualTo(
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
assertThat(e.getNullRange()).isNull();
assertThat(e.getIntegerRangeList()).containsExactly(Range.closed(2, 5));
});
}
@@ -1026,8 +1065,7 @@ public class MappingElasticsearchConverterUnitTests {
entity.setZonedDateTimeRange(
Range.just(ZonedDateTime.of(LocalDate.of(2021, 1, 1), LocalTime.of(0, 30), ZoneOffset.ofHours(2))));
entity.setNullRange(null);
// when
entity.setIntegerRangeList(List.of(Range.closed(2, 5)));
Document document = mappingElasticsearchConverter.mapObject(entity);
// then
@@ -1052,6 +1090,8 @@ public class MappingElasticsearchConverterUnitTests {
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;
@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;
public String getId() {
return id;
}
@@ -1148,6 +1188,13 @@ public class MappingElasticsearchConverterUnitTests {
this.nullRange = nullRange;
}
public List<Range<Integer>> getIntegerRangeList() {
return integerRangeList;
}
public void setIntegerRangeList(List<Range<Integer>> integerRangeList) {
this.integerRangeList = integerRangeList;
}
}
}
@@ -63,13 +63,14 @@ public class PropertyValueConvertersUnitTests {
converters.add(new DatePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
Class<?> genericType = Object.class;
converters.add(new DateRangePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new NumberRangePropertyValueConverter(persistentProperty));
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new NumberRangePropertyValueConverter(persistentProperty, genericType));
converters.add(new TemporalPropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
converters.add(new TemporalRangePropertyValueConverter(persistentProperty,
Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
genericType, Collections.singletonList(ElasticsearchDateConverter.of(DateFormat.basic_date))));
return converters.stream().map(propertyValueConverter -> arguments(
Named.of(propertyValueConverter.getClass().getSimpleName(), propertyValueConverter)));