Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab4fd17520 | |||
| 6045f1e0e3 | |||
| 102d7370bd | |||
| e22ba228a9 | |||
| 52105fcdcc | |||
| 8a1242fdbd | |||
| 5f78ab8e25 | |||
| 0899df94eb | |||
| 327e0a207c | |||
| 8d044fe3d1 | |||
| 642d95b5d1 | |||
| 6092da6fe7 | |||
| 4773da32ab | |||
| 642e42e01e | |||
| 0820ede014 | |||
| fb49aaa2d6 | |||
| c67b3082cb | |||
| 0784cc7226 | |||
| 2ce1bddce9 | |||
| 48d2cd1461 | |||
| bdee49f815 | |||
| aae7734bc0 | |||
| 054c02bd41 | |||
| 4798136074 | |||
| 389a5bc5e7 | |||
| fea26b5751 | |||
| fd7a380edd | |||
| ff021c1319 | |||
| ae38eab00d |
Vendored
+3
-3
@@ -31,7 +31,7 @@ pipeline {
|
||||
options { timeout(time: 30, unit: 'MINUTES') }
|
||||
steps {
|
||||
sh 'rm -rf ?'
|
||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -B'
|
||||
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ pipeline {
|
||||
"-Dartifactory.staging-repository=libs-snapshot-local " +
|
||||
"-Dartifactory.build-name=spring-data-elasticsearch " +
|
||||
"-Dartifactory.build-number=${BUILD_NUMBER} " +
|
||||
'-Dmaven.test.skip=true clean deploy -B'
|
||||
'-Dmaven.test.skip=true clean deploy -U -B'
|
||||
}
|
||||
}
|
||||
stage('Publish documentation') {
|
||||
@@ -91,7 +91,7 @@ pipeline {
|
||||
"-Dartifactory.username=${ARTIFACTORY_USR} " +
|
||||
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
|
||||
"-Dartifactory.distribution-repository=temp-private-local " +
|
||||
'-Dmaven.test.skip=true clean deploy -B'
|
||||
'-Dmaven.test.skip=true clean deploy -U -B'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-11
@@ -118,16 +118,7 @@ Add the Maven dependency:
|
||||
// Always change both files!
|
||||
**Compatibility Matrix**
|
||||
|
||||
[cols="^,^,"]
|
||||
|===
|
||||
|Spring Data Elasticsearch | Elasticsearch |
|
||||
| _3.2.x_ |_6.8.1_ | _not yet released_
|
||||
|3.1.x |6.2.2
|
||||
|3.0.x |5.5.0
|
||||
|2.1.x |2.4.0
|
||||
|2.0.x |2.2.0
|
||||
|1.3.x |1.5.2
|
||||
|===
|
||||
The compatibility between Spring Data Elasticsearch, Elasticsearch client drivers and Spring Boot versions can be found in the https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RC3/reference/html/#preface.versions[reference documentation].
|
||||
|
||||
To use the Release candidate versions of the upcoming major version, use our Maven milestone repository and declare the appropriate dependency version:
|
||||
|
||||
@@ -214,7 +205,7 @@ The generated documentation is available from `target/site/reference/html/index.
|
||||
|
||||
== Examples
|
||||
|
||||
For examples on using the _Spring Data for Elasticsearch, see the https://github.com/SpringSource/spring-elasticsearch-examples[spring-elasticsearch-examples] project.
|
||||
For examples on using the Spring Data for Elasticsearch, see the https://github.com/spring-projects/spring-data-examples/tree/master/elasticsearch/example[spring-data-examples] project.
|
||||
|
||||
== License
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>3.2.0.RC2</version>
|
||||
<version>3.2.0.RELEASE</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>2.2.0.RC2</version>
|
||||
<version>2.2.0.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
@@ -21,7 +21,8 @@
|
||||
<commonslang>2.6</commonslang>
|
||||
<elasticsearch>6.8.1</elasticsearch>
|
||||
<log4j>2.9.1</log4j>
|
||||
<springdata.commons>2.2.0.RC2</springdata.commons>
|
||||
<springdata.commons>2.2.0.RELEASE</springdata.commons>
|
||||
<netty>4.1.39.Final</netty>
|
||||
<java-module-name>spring.data.elasticsearch</java-module-name>
|
||||
</properties>
|
||||
|
||||
@@ -72,6 +73,19 @@
|
||||
<url>https://jira.spring.io/browse/DATAES</url>
|
||||
</issueManagement>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-bom</artifactId>
|
||||
<version>${netty}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- Spring -->
|
||||
@@ -315,8 +329,8 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-libs-milestone</id>
|
||||
<url>https://repo.spring.io/libs-milestone</url>
|
||||
<id>spring-libs-release</id>
|
||||
<url>https://repo.spring.io/libs-release</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
@@ -31,15 +31,14 @@ Requires an installation of https://www.elastic.co/products/elasticsearch[Elasti
|
||||
// this file is duplicated in the toplevel README
|
||||
// Always change both files!
|
||||
|
||||
The following table shows the Elasticsearch versions that are used by Spring Data Elasticsearch:
|
||||
[cols="^,^"]
|
||||
The following table shows the Elasticsearch versions that are used by Spring Data release trains and version of Spring Data Elasticsearch included in that, as well as the Spring Boot versions refering to that particular Spring Data release train:
|
||||
[cols="^,^,^,^",options="header"]
|
||||
|===
|
||||
|Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot
|
||||
|Moorefootnote:cdv[Currently in development] |3.2.xfootnote:cdv[]|6.8.1 / 7.xfootnote:hrc[via the <<elasticsearch.clients.rest,high-level REST client>>]|2.2.0footnote:cdv[]
|
||||
|Lovelace |3.1.x |6.2.2 / 7.xfootnote:hrc[]|2.1.x
|
||||
|Kayfootnote:oom[Out of maintenance]|3.0.xfootnote:oom[] |5.5.0 |2.0.xfootnote:oom[]
|
||||
|Ingallsfootnote:oom[]|2.1.xfootnote:oom[] |2.4.0 |1.5.xfootnote:oom[]
|
||||
|===
|
||||
|Spring Data Elasticsearch |Elasticsearch
|
||||
|
||||
|3.2.x |6.8.1
|
||||
|3.1.x |6.2.2
|
||||
|3.0.x |5.5.0
|
||||
|2.1.x |2.4.0
|
||||
|2.0.x |2.2.0
|
||||
|1.3.x |1.5.2
|
||||
|===
|
||||
Support for upcoming versions of Elasticsearch is being tracked and general compatibility should be given assuming the usage of the <<elasticsearch.clients.rest,high-level REST client>>.
|
||||
|
||||
+5
-130
@@ -15,31 +15,22 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.reactive.ClientHttpResponse;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.BodyExtractor;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.ExchangeStrategies;
|
||||
import org.springframework.web.reactive.function.client.WebClientResponseException;
|
||||
|
||||
/**
|
||||
* Extension to {@link ActionResponse} that also implements {@link ClientResponse}.
|
||||
* Extension to {@link ActionResponse} that also delegates to {@link ClientResponse}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Mark Paluch
|
||||
* @since 3.2
|
||||
*/
|
||||
class RawActionResponse extends ActionResponse implements ClientResponse {
|
||||
class RawActionResponse extends ActionResponse {
|
||||
|
||||
private final ClientResponse delegate;
|
||||
|
||||
@@ -51,139 +42,23 @@ class RawActionResponse extends ActionResponse implements ClientResponse {
|
||||
return new RawActionResponse(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#statusCode()
|
||||
*/
|
||||
@Override
|
||||
public HttpStatus statusCode() {
|
||||
return delegate.statusCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#rawStatusCode()
|
||||
*/
|
||||
@Override
|
||||
public int rawStatusCode() {
|
||||
return delegate.rawStatusCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#headers()
|
||||
*/
|
||||
@Override
|
||||
public Headers headers() {
|
||||
public ClientResponse.Headers headers() {
|
||||
return delegate.headers();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#cookies()
|
||||
*/
|
||||
@Override
|
||||
public MultiValueMap<String, ResponseCookie> cookies() {
|
||||
return delegate.cookies();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#strategies()
|
||||
*/
|
||||
@Override
|
||||
public ExchangeStrategies strategies() {
|
||||
return delegate.strategies();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#body(org.springframework.web.reactive.function.BodyExtractor)
|
||||
*/
|
||||
@Override
|
||||
public <T> T body(BodyExtractor<T, ? super ClientHttpResponse> extractor) {
|
||||
return delegate.body(extractor);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToMono(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) {
|
||||
return delegate.bodyToMono(elementClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToMono(org.springframework.core.ParameterizedTypeReference)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> typeReference) {
|
||||
return delegate.bodyToMono(typeReference);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToFlux(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) {
|
||||
return delegate.bodyToFlux(elementClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToFlux(org.springframework.core.ParameterizedTypeReference)
|
||||
*/
|
||||
@Override
|
||||
public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference) {
|
||||
return delegate.bodyToFlux(typeReference);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntity(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<ResponseEntity<T>> toEntity(Class<T> bodyType) {
|
||||
return delegate.toEntity(bodyType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntity(org.springframework.core.ParameterizedTypeReference)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<ResponseEntity<T>> toEntity(ParameterizedTypeReference<T> typeReference) {
|
||||
return delegate.toEntity(typeReference);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntityList(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<ResponseEntity<List<T>>> toEntityList(Class<T> elementType) {
|
||||
return delegate.toEntityList(elementType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntityList(org.springframework.core.ParameterizedTypeReference)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<ResponseEntity<List<T>>> toEntityList(ParameterizedTypeReference<T> typeReference) {
|
||||
return delegate.toEntityList(typeReference);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.reactive.function.client.ClientResponse#createException()
|
||||
*/
|
||||
@Override
|
||||
public Mono<WebClientResponseException> createException() {
|
||||
return delegate.createException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
@@ -81,6 +81,7 @@ import org.elasticsearch.index.reindex.AbstractBulkByScrollRequest;
|
||||
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
|
||||
import org.elasticsearch.index.reindex.ReindexRequest;
|
||||
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
|
||||
import org.elasticsearch.index.seqno.SequenceNumbers;
|
||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||
import org.elasticsearch.tasks.TaskId;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
@@ -116,6 +117,8 @@ public class RequestConverters {
|
||||
parameters.withTimeout(deleteRequest.timeout());
|
||||
parameters.withVersion(deleteRequest.version());
|
||||
parameters.withVersionType(deleteRequest.versionType());
|
||||
parameters.withIfSeqNo(deleteRequest.ifSeqNo());
|
||||
parameters.withIfPrimaryTerm(deleteRequest.ifPrimaryTerm());
|
||||
parameters.withRefreshPolicy(deleteRequest.getRefreshPolicy());
|
||||
parameters.withWaitForActiveShards(deleteRequest.waitForActiveShards());
|
||||
return request;
|
||||
@@ -315,6 +318,8 @@ public class RequestConverters {
|
||||
parameters.withTimeout(indexRequest.timeout());
|
||||
parameters.withVersion(indexRequest.version());
|
||||
parameters.withVersionType(indexRequest.versionType());
|
||||
parameters.withIfSeqNo(indexRequest.ifSeqNo());
|
||||
parameters.withIfPrimaryTerm(indexRequest.ifPrimaryTerm());
|
||||
parameters.withPipeline(indexRequest.getPipeline());
|
||||
parameters.withRefreshPolicy(indexRequest.getRefreshPolicy());
|
||||
parameters.withWaitForActiveShards(indexRequest.waitForActiveShards());
|
||||
@@ -917,6 +922,20 @@ public class RequestConverters {
|
||||
return this;
|
||||
}
|
||||
|
||||
Params withIfSeqNo(long seqNo) {
|
||||
if (seqNo != SequenceNumbers.UNASSIGNED_SEQ_NO) {
|
||||
return putParam("if_seq_no", Long.toString(seqNo));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Params withIfPrimaryTerm(long primaryTerm) {
|
||||
if (primaryTerm != SequenceNumbers.UNASSIGNED_PRIMARY_TERM) {
|
||||
return putParam("if_primary_term", Long.toString(primaryTerm));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Params withWaitForActiveShards(ActiveShardCount activeShardCount) {
|
||||
return withWaitForActiveShards(activeShardCount, ActiveShardCount.DEFAULT);
|
||||
}
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* AbstractElasticsearchTemplate
|
||||
*
|
||||
* @author Sascha Woo
|
||||
*/
|
||||
public abstract class AbstractElasticsearchTemplate {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
|
||||
|
||||
protected ElasticsearchConverter elasticsearchConverter;
|
||||
|
||||
public AbstractElasticsearchTemplate(ElasticsearchConverter elasticsearchConverter) {
|
||||
|
||||
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null.");
|
||||
this.elasticsearchConverter = elasticsearchConverter;
|
||||
}
|
||||
|
||||
protected String buildMapping(Class<?> clazz) {
|
||||
|
||||
// load mapping specified in Mapping annotation if present
|
||||
if (clazz.isAnnotationPresent(Mapping.class)) {
|
||||
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
|
||||
if (!StringUtils.isEmpty(mappingPath)) {
|
||||
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
|
||||
if (!StringUtils.isEmpty(mappings)) {
|
||||
return mappings;
|
||||
}
|
||||
} else {
|
||||
LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
|
||||
}
|
||||
}
|
||||
|
||||
// build mapping from field annotations
|
||||
try {
|
||||
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
|
||||
return mappingBuilder.buildPropertyMapping(clazz);
|
||||
} catch (Exception e) {
|
||||
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -104,6 +104,16 @@ public interface ElasticsearchOperations {
|
||||
*/
|
||||
<T> boolean putMapping(Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Create mapping for the given class and put the mapping to the given indexName and type.
|
||||
*
|
||||
* @param indexName
|
||||
* @param type
|
||||
* @param mappings
|
||||
* @since 3.2
|
||||
*/
|
||||
<T> boolean putMapping(String indexName, String type, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Create mapping for a given indexName and type
|
||||
*
|
||||
|
||||
+100
-51
@@ -22,6 +22,7 @@ import static org.springframework.util.StringUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -78,6 +79,7 @@ import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||
import org.elasticsearch.search.sort.ScoreSortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilder;
|
||||
import org.elasticsearch.search.sort.SortBuilders;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
@@ -92,7 +94,6 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||
import org.springframework.data.elasticsearch.core.client.support.AliasData;
|
||||
@@ -140,13 +141,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Martin Choraine
|
||||
* @author Farid Azaza
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Mathias Teier
|
||||
* @author Gyula Attila Csorogi
|
||||
*/
|
||||
public class ElasticsearchRestTemplate
|
||||
public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
|
||||
implements ElasticsearchOperations, EsClient<RestHighLevelClient>, ApplicationContextAware {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
|
||||
|
||||
private RestHighLevelClient client;
|
||||
private ElasticsearchConverter elasticsearchConverter;
|
||||
private ResultsMapper resultsMapper;
|
||||
private String searchTimeout;
|
||||
|
||||
@@ -175,8 +178,9 @@ public class ElasticsearchRestTemplate
|
||||
public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter,
|
||||
ResultsMapper resultsMapper) {
|
||||
|
||||
super(elasticsearchConverter);
|
||||
|
||||
Assert.notNull(client, "Client must not be null!");
|
||||
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
|
||||
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
|
||||
|
||||
this.client = client;
|
||||
@@ -223,11 +227,17 @@ public class ElasticsearchRestTemplate
|
||||
|
||||
@Override
|
||||
public boolean removeAlias(AliasQuery query) {
|
||||
|
||||
Assert.notNull(query.getIndexName(), "No index defined for Alias");
|
||||
Assert.notNull(query.getAliasName(), "No alias defined");
|
||||
IndicesAliasesRequest request = new IndicesAliasesRequest();
|
||||
AliasActions aliasAction = new AliasActions(AliasActions.Type.REMOVE);
|
||||
request.addAliasAction(aliasAction);
|
||||
|
||||
AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() //
|
||||
.index(query.getIndexName()) //
|
||||
.alias(query.getAliasName());
|
||||
|
||||
IndicesAliasesRequest request = Requests.indexAliasesRequest() //
|
||||
.addAliasAction(aliasAction);
|
||||
|
||||
try {
|
||||
return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged();
|
||||
} catch (IOException e) {
|
||||
@@ -252,23 +262,7 @@ public class ElasticsearchRestTemplate
|
||||
|
||||
@Override
|
||||
public <T> boolean putMapping(Class<T> clazz) {
|
||||
if (clazz.isAnnotationPresent(Mapping.class)) {
|
||||
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
|
||||
if (hasText(mappingPath)) {
|
||||
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
|
||||
if (hasText(mappings)) {
|
||||
return putMapping(clazz, mappings);
|
||||
}
|
||||
} else {
|
||||
logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
|
||||
}
|
||||
}
|
||||
try {
|
||||
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
|
||||
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
|
||||
} catch (Exception e) {
|
||||
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
|
||||
}
|
||||
return putMapping(clazz, buildMapping(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -277,6 +271,11 @@ public class ElasticsearchRestTemplate
|
||||
mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean putMapping(String indexName, String type, Class<T> clazz) {
|
||||
return putMapping(indexName, type, buildMapping(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putMapping(String indexName, String type, Object mapping) {
|
||||
Assert.notNull(indexName, "No index defined for putMapping()");
|
||||
@@ -714,26 +713,39 @@ public class ElasticsearchRestTemplate
|
||||
}
|
||||
|
||||
private UpdateRequest prepareUpdate(UpdateQuery query) {
|
||||
|
||||
String indexName = hasText(query.getIndexName()) ? query.getIndexName()
|
||||
: getPersistentEntityFor(query.getClazz()).getIndexName();
|
||||
String type = hasText(query.getType()) ? query.getType() : getPersistentEntityFor(query.getClazz()).getIndexType();
|
||||
|
||||
Assert.notNull(indexName, "No index defined for Query");
|
||||
Assert.notNull(type, "No type define for Query");
|
||||
Assert.notNull(query.getId(), "No Id define for Query");
|
||||
Assert.notNull(query.getUpdateRequest(), "No IndexRequest define for Query");
|
||||
UpdateRequest updateRequest = new UpdateRequest(indexName, type, query.getId());
|
||||
updateRequest.routing(query.getUpdateRequest().routing());
|
||||
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
|
||||
|
||||
if (query.getUpdateRequest().script() == null) {
|
||||
// doc
|
||||
if (query.DoUpsert()) {
|
||||
updateRequest.docAsUpsert(true).doc(query.getUpdateRequest().doc());
|
||||
} else {
|
||||
updateRequest.doc(query.getUpdateRequest().doc());
|
||||
}
|
||||
} else {
|
||||
// or script
|
||||
updateRequest.script(query.getUpdateRequest().script());
|
||||
UpdateRequest queryUpdateRequest = query.getUpdateRequest();
|
||||
|
||||
UpdateRequest updateRequest = new UpdateRequest(indexName, type, query.getId()) //
|
||||
.routing(queryUpdateRequest.routing()) //
|
||||
.retryOnConflict(queryUpdateRequest.retryOnConflict()) //
|
||||
.timeout(queryUpdateRequest.timeout()) //
|
||||
.waitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
|
||||
.setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) //
|
||||
.waitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
|
||||
.scriptedUpsert(queryUpdateRequest.scriptedUpsert()) //
|
||||
.docAsUpsert(queryUpdateRequest.docAsUpsert());
|
||||
|
||||
if (query.DoUpsert()) {
|
||||
updateRequest.docAsUpsert(true);
|
||||
}
|
||||
if (queryUpdateRequest.script() != null) {
|
||||
updateRequest.script(queryUpdateRequest.script());
|
||||
}
|
||||
if (queryUpdateRequest.doc() != null) {
|
||||
updateRequest.doc(queryUpdateRequest.doc());
|
||||
}
|
||||
if (queryUpdateRequest.upsertRequest() != null) {
|
||||
updateRequest.upsert(queryUpdateRequest.upsertRequest());
|
||||
}
|
||||
|
||||
return updateRequest;
|
||||
@@ -948,6 +960,23 @@ public class ElasticsearchRestTemplate
|
||||
prepareSort(query, searchSourceBuilder, entity);
|
||||
}
|
||||
|
||||
if (query instanceof SearchQuery) {
|
||||
SearchQuery searchQuery = (SearchQuery) query;
|
||||
|
||||
if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) {
|
||||
HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder();
|
||||
if (highlightBuilder == null) {
|
||||
highlightBuilder = new HighlightBuilder();
|
||||
}
|
||||
if (searchQuery.getHighlightFields() != null) {
|
||||
for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) {
|
||||
highlightBuilder.field(highlightField);
|
||||
}
|
||||
}
|
||||
searchSourceBuilder.highlighter(highlightBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
request.source(searchSourceBuilder);
|
||||
return request;
|
||||
}
|
||||
@@ -1328,25 +1357,44 @@ public class ElasticsearchRestTemplate
|
||||
request.preference(query.getPreference());
|
||||
}
|
||||
|
||||
if (query.getSearchType() != null) {
|
||||
request.searchType(query.getSearchType());
|
||||
}
|
||||
|
||||
request.source(sourceBuilder);
|
||||
return request;
|
||||
}
|
||||
|
||||
private void prepareSort(Query query, SearchSourceBuilder sourceBuilder,
|
||||
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||
|
||||
for (Sort.Order order : query.getSort()) {
|
||||
ElasticsearchPersistentProperty property = entity != null //
|
||||
? entity.getPersistentProperty(order.getProperty()) //
|
||||
: null;
|
||||
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
||||
FieldSortBuilder sort = SortBuilders.fieldSort(fieldName)
|
||||
.order(order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC);
|
||||
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
||||
sort.missing("_first");
|
||||
} else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
|
||||
sort.missing("_last");
|
||||
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
|
||||
|
||||
if (ScoreSortBuilder.NAME.equals(order.getProperty())) {
|
||||
ScoreSortBuilder sort = SortBuilders //
|
||||
.scoreSort() //
|
||||
.order(sortOrder);
|
||||
|
||||
sourceBuilder.sort(sort);
|
||||
} else {
|
||||
ElasticsearchPersistentProperty property = (entity != null) //
|
||||
? entity.getPersistentProperty(order.getProperty()) //
|
||||
: null;
|
||||
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
||||
|
||||
FieldSortBuilder sort = SortBuilders //
|
||||
.fieldSort(fieldName) //
|
||||
.order(sortOrder);
|
||||
|
||||
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
||||
sort.missing("_first");
|
||||
} else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
|
||||
sort.missing("_last");
|
||||
}
|
||||
|
||||
sourceBuilder.sort(sort);
|
||||
}
|
||||
sourceBuilder.sort(sort);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1439,11 +1487,12 @@ public class ElasticsearchRestTemplate
|
||||
|
||||
try {
|
||||
JsonNode node = mapper.readTree(aliasResponse);
|
||||
|
||||
Iterator<String> names = node.fieldNames();
|
||||
String name = names.next();
|
||||
node = node.findValue("aliases");
|
||||
|
||||
if (node == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Map<String, AliasData> aliasData = mapper.readValue(mapper.writeValueAsString(node),
|
||||
new TypeReference<Map<String, AliasData>>() {});
|
||||
|
||||
|
||||
+57
-38
@@ -47,6 +47,7 @@ import org.elasticsearch.action.search.MultiSearchRequest;
|
||||
import org.elasticsearch.action.search.MultiSearchResponse;
|
||||
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.update.UpdateRequest;
|
||||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||
import org.elasticsearch.action.update.UpdateResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
@@ -82,7 +83,6 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Mapping;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
@@ -122,16 +122,16 @@ import org.springframework.util.StringUtils;
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Martin Choraine
|
||||
* @author Farid Azaza
|
||||
* @author Gyula Attila Csorogi
|
||||
*/
|
||||
public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
|
||||
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
|
||||
implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
|
||||
|
||||
private static final Logger QUERY_LOGGER = LoggerFactory
|
||||
.getLogger("org.springframework.data.elasticsearch.core.QUERY");
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchTemplate.class);
|
||||
private static final String FIELD_SCORE = "_score";
|
||||
|
||||
private Client client;
|
||||
private ElasticsearchConverter elasticsearchConverter;
|
||||
private ResultsMapper resultsMapper;
|
||||
private String searchTimeout;
|
||||
|
||||
@@ -160,12 +160,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter,
|
||||
ResultsMapper resultsMapper) {
|
||||
|
||||
super(elasticsearchConverter);
|
||||
|
||||
Assert.notNull(client, "Client must not be null!");
|
||||
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
|
||||
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
|
||||
|
||||
this.client = client;
|
||||
this.elasticsearchConverter = elasticsearchConverter;
|
||||
this.resultsMapper = resultsMapper;
|
||||
}
|
||||
|
||||
@@ -220,23 +220,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
|
||||
@Override
|
||||
public <T> boolean putMapping(Class<T> clazz) {
|
||||
if (clazz.isAnnotationPresent(Mapping.class)) {
|
||||
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
|
||||
if (!StringUtils.isEmpty(mappingPath)) {
|
||||
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
|
||||
if (!StringUtils.isEmpty(mappings)) {
|
||||
return putMapping(clazz, mappings);
|
||||
}
|
||||
} else {
|
||||
LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
|
||||
}
|
||||
}
|
||||
try {
|
||||
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
|
||||
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
|
||||
} catch (Exception e) {
|
||||
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
|
||||
}
|
||||
return putMapping(clazz, buildMapping(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,6 +229,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean putMapping(String indexName, String type, Class<T> clazz) {
|
||||
return putMapping(indexName, type, buildMapping(clazz));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putMapping(String indexName, String type, Object mapping) {
|
||||
Assert.notNull(indexName, "No index defined for putMapping()");
|
||||
@@ -609,27 +598,40 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
}
|
||||
|
||||
private UpdateRequestBuilder prepareUpdate(UpdateQuery query) {
|
||||
|
||||
String indexName = !StringUtils.isEmpty(query.getIndexName()) ? query.getIndexName()
|
||||
: getPersistentEntityFor(query.getClazz()).getIndexName();
|
||||
String type = !StringUtils.isEmpty(query.getType()) ? query.getType()
|
||||
: getPersistentEntityFor(query.getClazz()).getIndexType();
|
||||
|
||||
Assert.notNull(indexName, "No index defined for Query");
|
||||
Assert.notNull(type, "No type define for Query");
|
||||
Assert.notNull(query.getId(), "No Id define for Query");
|
||||
Assert.notNull(query.getUpdateRequest(), "No IndexRequest define for Query");
|
||||
UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, type, query.getId());
|
||||
updateRequestBuilder.setRouting(query.getUpdateRequest().routing());
|
||||
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
|
||||
|
||||
if (query.getUpdateRequest().script() == null) {
|
||||
// doc
|
||||
if (query.DoUpsert()) {
|
||||
updateRequestBuilder.setDocAsUpsert(true).setDoc(query.getUpdateRequest().doc());
|
||||
} else {
|
||||
updateRequestBuilder.setDoc(query.getUpdateRequest().doc());
|
||||
}
|
||||
} else {
|
||||
// or script
|
||||
updateRequestBuilder.setScript(query.getUpdateRequest().script());
|
||||
UpdateRequest queryUpdateRequest = query.getUpdateRequest();
|
||||
|
||||
UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, type, query.getId()) //
|
||||
.setRouting(queryUpdateRequest.routing()) //
|
||||
.setRetryOnConflict(queryUpdateRequest.retryOnConflict()) //
|
||||
.setTimeout(queryUpdateRequest.timeout()) //
|
||||
.setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
|
||||
.setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) //
|
||||
.setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
|
||||
.setScriptedUpsert(queryUpdateRequest.scriptedUpsert()) //
|
||||
.setDocAsUpsert(queryUpdateRequest.docAsUpsert());
|
||||
|
||||
if (query.DoUpsert()) {
|
||||
updateRequestBuilder.setDocAsUpsert(true);
|
||||
}
|
||||
if (queryUpdateRequest.script() != null) {
|
||||
updateRequestBuilder.setScript(queryUpdateRequest.script());
|
||||
}
|
||||
if (queryUpdateRequest.doc() != null) {
|
||||
updateRequestBuilder.setDoc(queryUpdateRequest.doc());
|
||||
}
|
||||
if (queryUpdateRequest.upsertRequest() != null) {
|
||||
updateRequestBuilder.setUpsert(queryUpdateRequest.upsertRequest());
|
||||
}
|
||||
|
||||
return updateRequestBuilder;
|
||||
@@ -808,6 +810,23 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
prepareSort(query, requestBuilder, entity);
|
||||
}
|
||||
|
||||
if (query instanceof SearchQuery) {
|
||||
SearchQuery searchQuery = (SearchQuery) query;
|
||||
|
||||
if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) {
|
||||
HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder();
|
||||
if (highlightBuilder == null) {
|
||||
highlightBuilder = new HighlightBuilder();
|
||||
}
|
||||
if (searchQuery.getHighlightFields() != null) {
|
||||
for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) {
|
||||
highlightBuilder.field(highlightField);
|
||||
}
|
||||
}
|
||||
requestBuilder.highlighter(highlightBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
return requestBuilder;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1091,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
|
||||
private <T> SearchRequestBuilder prepareSearch(Query query, Class<T> clazz) {
|
||||
setPersistentEntityIndexAndType(query, clazz);
|
||||
return prepareSearch(query, getPersistentEntity(clazz));
|
||||
return prepareSearch(query, getPersistentEntity(clazz));
|
||||
}
|
||||
|
||||
private SearchRequestBuilder prepareSearch(Query query, @Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||
@@ -1123,7 +1142,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
||||
for (Sort.Order order : query.getSort()) {
|
||||
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
|
||||
|
||||
if (FIELD_SCORE.equals(order.getProperty())) {
|
||||
if (ScoreSortBuilder.NAME.equals(order.getProperty())) {
|
||||
ScoreSortBuilder sort = SortBuilders //
|
||||
.scoreSort() //
|
||||
.order(sortOrder);
|
||||
|
||||
+5
@@ -78,6 +78,7 @@ import org.springframework.util.Assert;
|
||||
* @author Farid Azaza
|
||||
* @author Martin Choraine
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Mathias Teier
|
||||
* @since 3.2
|
||||
*/
|
||||
public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations {
|
||||
@@ -283,6 +284,10 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
||||
request.preference(query.getPreference());
|
||||
}
|
||||
|
||||
if (query.getSearchType() != null) {
|
||||
request.searchType(query.getSearchType());
|
||||
}
|
||||
|
||||
Pageable pageable = query.getPageable();
|
||||
|
||||
if (pageable.isPaged()) {
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
|
||||
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
|
||||
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
|
||||
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
|
||||
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
|
||||
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
Spring Data Elasticsearch Changelog
|
||||
===================================
|
||||
|
||||
Changes in version 3.2.0.RELEASE (2019-09-30)
|
||||
---------------------------------------------
|
||||
* DATAES-657 - Sort by _score not supported by ElasticsearchRestTemplate.
|
||||
* DATAES-652 - Send if_seq_no and if_primary_term parameters when indexing via ReactiveElasticsearchClient.
|
||||
* DATAES-648 - Unify documentation of version compatibilities.
|
||||
* DATAES-625 - Release 3.2 GA (Moore).
|
||||
* DATAES-541 - IllegalArgumentException on ElasticsearchRestTemplate#removeAlias.
|
||||
* DATAES-305 - let users create mappings with dynamical indexName.
|
||||
* DATAES-227 - ElasticsearchTemplate.prepareUpdate should call setUpsert.
|
||||
|
||||
|
||||
Changes in version 3.1.11.RELEASE (2019-09-30)
|
||||
----------------------------------------------
|
||||
* DATAES-627 - Add HTTPS entries into spring.schemas.
|
||||
* DATAES-624 - Release 3.1.11 (Lovelace SR11).
|
||||
|
||||
|
||||
Changes in version 3.2.0.RC3 (2019-09-06)
|
||||
-----------------------------------------
|
||||
* DATAES-646 - Adapt to Spring Framework 5.2 RC2.
|
||||
* DATAES-645 - Missing highlight support for scrolling queries.
|
||||
* DATAES-643 - RestTemplate ignores search_type.
|
||||
* DATAES-627 - Add HTTPS entries into spring.schemas.
|
||||
* DATAES-626 - Release 3.2 RC3 (Moore).
|
||||
|
||||
|
||||
Changes in version 3.2.0.RC2 (2019-08-05)
|
||||
-----------------------------------------
|
||||
* DATAES-619 - Migrate remaining tests to AssertJ.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Elasticsearch 3.2 RC2
|
||||
Spring Data Elasticsearch 3.2 GA
|
||||
Copyright (c) [2013-2019] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2018-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.client.util;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.elasticsearch.action.delete.DeleteRequest;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.client.Request;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RequestConverters}.
|
||||
*
|
||||
* @author Roman Puchkovskiy
|
||||
*/
|
||||
public class RequestConvertersTest {
|
||||
@Test // DATAES-652
|
||||
public void shouldNotAddIfSeqNoAndIfPrimaryTermToResultIfInputDoesNotcontainThemWhenConvertingIndexRequest() {
|
||||
IndexRequest request = createMinimalIndexRequest();
|
||||
|
||||
Request result = RequestConverters.index(request);
|
||||
|
||||
assertThat(result.getParameters(), not(hasKey("if_seq_no")));
|
||||
assertThat(result.getParameters(), not(hasKey("if_primary_term")));
|
||||
}
|
||||
|
||||
private IndexRequest createMinimalIndexRequest() {
|
||||
IndexRequest request = new IndexRequest("the-index", "the-type", "id");
|
||||
request.source(new HashMap<String, String>() {
|
||||
{
|
||||
put("test", "test");
|
||||
}
|
||||
});
|
||||
return request;
|
||||
}
|
||||
|
||||
@Test // DATAES-652
|
||||
public void shouldAddIfSeqNoAndIfPrimaryTermToResultIfInputcontainsThemWhenConvertingIndexRequest() {
|
||||
IndexRequest request = createMinimalIndexRequest();
|
||||
request.setIfSeqNo(3);
|
||||
request.setIfPrimaryTerm(4);
|
||||
|
||||
Request result = RequestConverters.index(request);
|
||||
|
||||
assertThat(result.getParameters(), hasEntry("if_seq_no", "3"));
|
||||
assertThat(result.getParameters(), hasEntry("if_primary_term", "4"));
|
||||
}
|
||||
|
||||
@Test // DATAES-652
|
||||
public void shouldNotAddIfSeqNoAndIfPrimaryTermToResultIfInputDoesNotcontainThemWhenConvertingDeleteRequest() {
|
||||
DeleteRequest request = createMinimalDeleteRequest();
|
||||
|
||||
Request result = RequestConverters.delete(request);
|
||||
|
||||
assertThat(result.getParameters(), not(hasKey("if_seq_no")));
|
||||
assertThat(result.getParameters(), not(hasKey("if_primary_term")));
|
||||
}
|
||||
|
||||
private DeleteRequest createMinimalDeleteRequest() {
|
||||
return new DeleteRequest("the-index", "the-type", "id");
|
||||
}
|
||||
|
||||
@Test // DATAES-652
|
||||
public void shouldAddIfSeqNoAndIfPrimaryTermToResultIfInputcontainsThemWhenConvertingDeleteRequest() {
|
||||
DeleteRequest request = createMinimalDeleteRequest();
|
||||
request.setIfSeqNo(3);
|
||||
request.setIfPrimaryTerm(4);
|
||||
|
||||
Request result = RequestConverters.delete(request);
|
||||
|
||||
assertThat(result.getParameters(), hasEntry("if_seq_no", "3"));
|
||||
assertThat(result.getParameters(), hasEntry("if_primary_term", "4"));
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014-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.apache.commons.lang.RandomStringUtils.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.lang.Long;
|
||||
import java.lang.Object;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.core.query.AliasBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.AliasQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
||||
import org.springframework.data.elasticsearch.utils.IndexInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Mohsin Husen
|
||||
* @author Ilkang Na
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
||||
public class AliasTests {
|
||||
|
||||
private static final String INDEX_NAME_1 = "test-alias-index-1";
|
||||
private static final String INDEX_NAME_2 = "test-alias-index-2";
|
||||
private static final String TYPE_NAME = "test-alias-type";
|
||||
|
||||
private static Map<String, Object> settings = new HashMap<>();
|
||||
static {
|
||||
settings.put("index.refresh_interval", "-1");
|
||||
settings.put("index.number_of_replicas", "0");
|
||||
settings.put("index.number_of_shards", "2");
|
||||
settings.put("index.store.type", "fs");
|
||||
}
|
||||
|
||||
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
elasticsearchTemplate.deleteIndex(INDEX_NAME_1);
|
||||
elasticsearchTemplate.createIndex(INDEX_NAME_1, settings);
|
||||
elasticsearchTemplate.refresh(INDEX_NAME_1);
|
||||
|
||||
elasticsearchTemplate.deleteIndex(INDEX_NAME_2);
|
||||
elasticsearchTemplate.createIndex(INDEX_NAME_2, settings);
|
||||
elasticsearchTemplate.refresh(INDEX_NAME_2);
|
||||
|
||||
IndexInitializer.init(elasticsearchTemplate, AliasedEntity.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddAlias() {
|
||||
|
||||
// given
|
||||
String aliasName = "test-alias";
|
||||
AliasQuery aliasQuery = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(aliasName).build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
|
||||
assertThat(aliases).isNotNull();
|
||||
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemoveAlias() {
|
||||
|
||||
// given
|
||||
String indexName = INDEX_NAME_1;
|
||||
String aliasName = "test-alias";
|
||||
AliasQuery aliasQuery = new AliasBuilder().withIndexName(indexName).withAliasName(aliasName).build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(indexName);
|
||||
assertThat(aliases).isNotNull();
|
||||
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
|
||||
|
||||
// then
|
||||
elasticsearchTemplate.removeAlias(aliasQuery);
|
||||
aliases = elasticsearchTemplate.queryForAlias(indexName);
|
||||
assertThat(aliases).isEmpty();
|
||||
}
|
||||
|
||||
@Test // DATAES-70
|
||||
public void shouldAddAliasWithGivenRoutingValue() {
|
||||
|
||||
// given
|
||||
String alias = "test-alias";
|
||||
|
||||
AliasQuery aliasQuery = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(alias).withRouting("0")
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
|
||||
String documentId = randomNumeric(5);
|
||||
AliasedEntity aliasedEntity = AliasedEntity.builder().id(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(alias).withId(aliasedEntity.getId())
|
||||
.withType(TYPE_NAME).withObject(aliasedEntity).build();
|
||||
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(INDEX_NAME_1);
|
||||
|
||||
SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(alias)
|
||||
.withTypes(TYPE_NAME).build();
|
||||
long count = elasticsearchTemplate.count(query);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
|
||||
assertThat(aliases).isNotNull();
|
||||
AliasMetaData aliasMetaData = aliases.get(0);
|
||||
assertThat(aliasMetaData.alias()).isEqualTo(alias);
|
||||
assertThat(aliasMetaData.searchRouting()).isEqualTo("0");
|
||||
assertThat(aliasMetaData.indexRouting()).isEqualTo("0");
|
||||
assertThat(count).isEqualTo(1);
|
||||
|
||||
// cleanup
|
||||
elasticsearchTemplate.removeAlias(aliasQuery);
|
||||
}
|
||||
|
||||
@Test // DATAES-70
|
||||
public void shouldAddAliasForVariousRoutingValues() {
|
||||
|
||||
// given
|
||||
String alias1 = "test-alias-1";
|
||||
String alias2 = "test-alias-2";
|
||||
|
||||
AliasQuery aliasQuery1 = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(alias1).withIndexRouting("0")
|
||||
.build();
|
||||
|
||||
AliasQuery aliasQuery2 = new AliasBuilder().withIndexName(INDEX_NAME_2).withAliasName(alias2).withSearchRouting("1")
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery1);
|
||||
elasticsearchTemplate.addAlias(aliasQuery2);
|
||||
|
||||
String documentId = randomNumeric(5);
|
||||
AliasedEntity aliasedEntity = AliasedEntity.builder().id(documentId).message("some message")
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(alias1).withType(TYPE_NAME)
|
||||
.withId(aliasedEntity.getId()).withObject(aliasedEntity).build();
|
||||
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> responseAlias1 = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
|
||||
assertThat(responseAlias1).isNotNull();
|
||||
AliasMetaData aliasMetaData1 = responseAlias1.get(0);
|
||||
assertThat(aliasMetaData1.alias()).isEqualTo(alias1);
|
||||
assertThat(aliasMetaData1.indexRouting()).isEqualTo("0");
|
||||
|
||||
List<AliasMetaData> responseAlias2 = elasticsearchTemplate.queryForAlias(INDEX_NAME_2);
|
||||
assertThat(responseAlias2).isNotNull();
|
||||
AliasMetaData aliasMetaData2 = responseAlias2.get(0);
|
||||
assertThat(aliasMetaData2.alias()).isEqualTo(alias2);
|
||||
assertThat(aliasMetaData2.searchRouting()).isEqualTo("1");
|
||||
|
||||
// cleanup
|
||||
elasticsearchTemplate.removeAlias(aliasQuery1);
|
||||
elasticsearchTemplate.removeAlias(aliasQuery2);
|
||||
}
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document(indexName = "test-index-sample-core-alias", type = "test-type", shards = 1, replicas = 0,
|
||||
refreshInterval = "-1")
|
||||
static class AliasedEntity {
|
||||
|
||||
@Id private String id;
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Version private Long version;
|
||||
}
|
||||
}
|
||||
+34
-1
@@ -16,17 +16,22 @@
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import static org.apache.commons.lang.RandomStringUtils.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.update.UpdateRequest;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
@@ -34,6 +39,7 @@ import org.springframework.data.elasticsearch.core.query.UpdateQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* @author Rizwan Idrees
|
||||
@@ -64,6 +70,33 @@ public class ElasticsearchRestTemplateTests extends ElasticsearchTemplateTests {
|
||||
elasticsearchTemplate.update(updateQuery);
|
||||
}
|
||||
|
||||
@Test // DATAES-227
|
||||
@Override
|
||||
public void shouldUseUpsertOnUpdate() throws IOException {
|
||||
|
||||
// given
|
||||
Map<String, Object> doc = new HashMap<>();
|
||||
doc.put("id", "1");
|
||||
doc.put("message", "test");
|
||||
|
||||
UpdateRequest updateRequest = new UpdateRequest() //
|
||||
.doc(doc) //
|
||||
.upsert(doc);
|
||||
|
||||
UpdateQuery updateQuery = new UpdateQueryBuilder() //
|
||||
.withClass(SampleEntity.class) //
|
||||
.withId("1") //
|
||||
.withUpdateRequest(updateRequest).build();
|
||||
|
||||
// when
|
||||
UpdateRequest request = (UpdateRequest) ReflectionTestUtils //
|
||||
.invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery);
|
||||
|
||||
// then
|
||||
assertThat(request).isNotNull();
|
||||
assertThat(request.upsertRequest()).isNotNull();
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0,
|
||||
|
||||
+284
-12
@@ -27,10 +27,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.lang.Double;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Long;
|
||||
import java.lang.Object;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@@ -49,6 +46,9 @@ import org.elasticsearch.action.get.MultiGetResponse;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.update.UpdateRequest;
|
||||
import org.elasticsearch.action.update.UpdateRequestBuilder;
|
||||
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||
import org.elasticsearch.index.VersionType;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.script.ScriptType;
|
||||
@@ -81,10 +81,12 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField;
|
||||
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.elasticsearch.core.query.*;
|
||||
import org.springframework.data.util.CloseableIterator;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* Base for testing rest/transport templates
|
||||
@@ -107,6 +109,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Martin Choraine
|
||||
* @author Farid Azaza
|
||||
* @author Gyula Attila Csorogi
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
|
||||
@@ -786,26 +789,30 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(sampleEntities.getContent().get(1).getMessage()).isEqualTo(sampleEntity2.getMessage());
|
||||
}
|
||||
|
||||
@Test // DATAES-467
|
||||
@Test // DATAES-467, DATAES-657
|
||||
public void shouldSortResultsByScore() {
|
||||
|
||||
// given
|
||||
List<SampleEntity> entities = Arrays.asList( //
|
||||
SampleEntity.builder().id("1").message("abc").build(), //
|
||||
SampleEntity.builder().id("2").message("def").build(), //
|
||||
SampleEntity.builder().id("3").message("ghi").build());
|
||||
SampleEntity.builder().id("1").message("green").build(), //
|
||||
SampleEntity.builder().id("2").message("yellow green").build(), //
|
||||
SampleEntity.builder().id("3").message("blue").build());
|
||||
|
||||
elasticsearchTemplate.bulkIndex(getIndexQueries(entities));
|
||||
elasticsearchTemplate.refresh(SampleEntity.class);
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
||||
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("_score")))).build();
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder() //
|
||||
.withQuery(matchQuery("message", "green")) //
|
||||
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("_score")))) //
|
||||
.build();
|
||||
|
||||
// when
|
||||
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
|
||||
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
|
||||
|
||||
// then
|
||||
assertThat(sampleEntities.getTotalElements()).isEqualTo(3);
|
||||
assertThat(page.getTotalElements()).isEqualTo(2);
|
||||
assertThat(page.getContent().get(0).getId()).isEqualTo("2");
|
||||
assertThat(page.getContent().get(1).getId()).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1435,6 +1442,22 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(elasticsearchTemplate.putMapping(entity)).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAES-305
|
||||
public void shouldPutMappingWithCustomIndexName() throws Exception {
|
||||
|
||||
// given
|
||||
Class<SampleEntity> entity = SampleEntity.class;
|
||||
elasticsearchTemplate.deleteIndex(INDEX_1_NAME);
|
||||
elasticsearchTemplate.createIndex(INDEX_1_NAME);
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.putMapping(INDEX_1_NAME, TYPE_NAME, entity);
|
||||
|
||||
// then
|
||||
Map<String, Object> mapping = elasticsearchTemplate.getMapping(INDEX_1_NAME, TYPE_NAME);
|
||||
assertThat(mapping.get("properties")).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteIndexForGivenEntity() {
|
||||
|
||||
@@ -1479,6 +1502,33 @@ public class ElasticsearchTemplateTests {
|
||||
assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate);
|
||||
}
|
||||
|
||||
@Test // DATAES-227
|
||||
public void shouldUseUpsertOnUpdate() throws IOException {
|
||||
|
||||
// given
|
||||
Map<String, Object> doc = new HashMap<>();
|
||||
doc.put("id", "1");
|
||||
doc.put("message", "test");
|
||||
|
||||
UpdateRequest updateRequest = new UpdateRequest() //
|
||||
.doc(doc) //
|
||||
.upsert(doc);
|
||||
|
||||
UpdateQuery updateQuery = new UpdateQueryBuilder() //
|
||||
.withClass(SampleEntity.class) //
|
||||
.withId("1") //
|
||||
.withUpdateRequest(updateRequest).build();
|
||||
|
||||
// when
|
||||
UpdateRequest request = ((UpdateRequestBuilder) ReflectionTestUtils //
|
||||
.invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery)) //
|
||||
.request();
|
||||
|
||||
// then
|
||||
assertThat(request).isNotNull();
|
||||
assertThat(request.upsertRequest()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDoUpsertIfDocumentDoesNotExist() {
|
||||
|
||||
@@ -1589,6 +1639,76 @@ public class ElasticsearchTemplateTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test // DATAES-645
|
||||
public void shouldReturnHighlightedFieldsInScroll() {
|
||||
|
||||
// given
|
||||
long scrollTimeInMillis = 3000;
|
||||
String documentId = randomNumeric(5);
|
||||
String actualType = "some test type";
|
||||
String actualMessage = "some test message";
|
||||
String highlightedType = "some <em>test</em> type";
|
||||
String highlightedMessage = "some <em>test</em> message";
|
||||
|
||||
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).type(actualType).message(actualMessage)
|
||||
.version(System.currentTimeMillis()).build();
|
||||
|
||||
IndexQuery indexQuery = getIndexQuery(sampleEntity);
|
||||
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(SampleEntity.class);
|
||||
|
||||
HighlightBuilder highlightBuilder = new HighlightBuilder().field("type").field("message");
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(boolQuery().must(termQuery("type", "test")).must(termQuery("message", "test")))
|
||||
.withPageable(PageRequest.of(0, 10)).withHighlightBuilder(highlightBuilder).build();
|
||||
|
||||
SearchResultMapper searchResultMapper = new SearchResultMapper() {
|
||||
@Override
|
||||
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
|
||||
DefaultEntityMapper defaultEntityMapper = new DefaultEntityMapper(new SimpleElasticsearchMappingContext());
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
|
||||
for (SearchHit searchHit : response.getHits()) {
|
||||
try {
|
||||
result.add((T) defaultEntityMapper.mapToObject(searchHit.getSourceAsString(), SampleEntity.class));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
|
||||
HighlightField highlightFieldType = highlightFields.get("type");
|
||||
HighlightField highlightFieldMessage = highlightFields.get("message");
|
||||
|
||||
// then
|
||||
assertThat(highlightFieldType).isNotNull();
|
||||
assertThat(highlightFieldMessage).isNotNull();
|
||||
assertThat(highlightFieldType.fragments()[0].toString()).isEqualTo(highlightedType);
|
||||
assertThat(highlightFieldMessage.fragments()[0].toString()).isEqualTo(highlightedMessage);
|
||||
}
|
||||
|
||||
return new AggregatedPageImpl<>(result, pageable, response.getHits().getTotalHits(), response.getAggregations(),
|
||||
response.getScrollId(), response.getHits().getMaxScore());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// when
|
||||
ScrolledPage<SampleEntity> scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery,
|
||||
SampleEntity.class, searchResultMapper);
|
||||
while (scroll.hasContent()) {
|
||||
scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class,
|
||||
searchResultMapper);
|
||||
}
|
||||
|
||||
elasticsearchTemplate.clearScroll(scroll.getScrollId());
|
||||
}
|
||||
|
||||
@Test // DATAES-479
|
||||
public void shouldHonorTheHighlightBuilderOptions() {
|
||||
|
||||
@@ -2869,6 +2989,158 @@ public class ElasticsearchTemplateTests {
|
||||
return indexQueries;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddAlias() {
|
||||
|
||||
// given
|
||||
String aliasName = "test-alias";
|
||||
AliasQuery aliasQuery = new AliasBuilder() //
|
||||
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
|
||||
.withAliasName(aliasName) //
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
|
||||
assertThat(aliases).isNotNull();
|
||||
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
|
||||
}
|
||||
|
||||
@Test // DATAES-70
|
||||
public void shouldAddAliasForVariousRoutingValues() {
|
||||
|
||||
// given
|
||||
String alias1 = "test-alias-1";
|
||||
String alias2 = "test-alias-2";
|
||||
|
||||
AliasQuery aliasQuery1 = new AliasBuilder() //
|
||||
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
|
||||
.withAliasName(alias1) //
|
||||
.withIndexRouting("0") //
|
||||
.build();
|
||||
|
||||
AliasQuery aliasQuery2 = new AliasBuilder() //
|
||||
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
|
||||
.withAliasName(alias2) //
|
||||
.withSearchRouting("1") //
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery1);
|
||||
elasticsearchTemplate.addAlias(aliasQuery2);
|
||||
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity entity = SampleEntity.builder() //
|
||||
.id(documentId) //
|
||||
.message("some message") //
|
||||
.version(System.currentTimeMillis()) //
|
||||
.build();
|
||||
|
||||
IndexQuery indexQuery = new IndexQueryBuilder() //
|
||||
.withIndexName(alias1) //
|
||||
.withType(TYPE_NAME) //
|
||||
.withId(entity.getId()) //
|
||||
.withObject(entity) //
|
||||
.build();
|
||||
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> aliasMetaData = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
|
||||
assertThat(aliasMetaData).isNotEmpty();
|
||||
|
||||
AliasMetaData aliasMetaData1 = aliasMetaData.get(0);
|
||||
assertThat(aliasMetaData1).isNotNull();
|
||||
assertThat(aliasMetaData1.alias()).isEqualTo(alias1);
|
||||
assertThat(aliasMetaData1.indexRouting()).isEqualTo("0");
|
||||
|
||||
AliasMetaData aliasMetaData2 = aliasMetaData.get(1);
|
||||
assertThat(aliasMetaData2).isNotNull();
|
||||
assertThat(aliasMetaData2.alias()).isEqualTo(alias2);
|
||||
assertThat(aliasMetaData2.searchRouting()).isEqualTo("1");
|
||||
|
||||
// cleanup
|
||||
elasticsearchTemplate.removeAlias(aliasQuery1);
|
||||
elasticsearchTemplate.removeAlias(aliasQuery2);
|
||||
}
|
||||
|
||||
@Test // DATAES-70
|
||||
public void shouldAddAliasWithGivenRoutingValue() {
|
||||
|
||||
// given
|
||||
String alias = "test-alias";
|
||||
|
||||
AliasQuery aliasQuery = new AliasBuilder() //
|
||||
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
|
||||
.withAliasName(alias) //
|
||||
.withRouting("0") //
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
|
||||
String documentId = randomNumeric(5);
|
||||
SampleEntity sampleEntity = SampleEntity.builder() //
|
||||
.id(documentId) //
|
||||
.message("some message") //
|
||||
.version(System.currentTimeMillis()) //
|
||||
.build();
|
||||
|
||||
IndexQuery indexQuery = new IndexQueryBuilder() //
|
||||
.withIndexName(alias) //
|
||||
.withId(sampleEntity.getId()) //
|
||||
.withType(TYPE_NAME) //
|
||||
.withObject(sampleEntity) //
|
||||
.build();
|
||||
|
||||
elasticsearchTemplate.index(indexQuery);
|
||||
elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY);
|
||||
|
||||
SearchQuery query = new NativeSearchQueryBuilder() //
|
||||
.withQuery(matchAllQuery()) //
|
||||
.withIndices(alias) //
|
||||
.withTypes(TYPE_NAME) //
|
||||
.build();
|
||||
|
||||
long count = elasticsearchTemplate.count(query);
|
||||
|
||||
// then
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
|
||||
assertThat(aliases).isNotNull();
|
||||
AliasMetaData aliasMetaData = aliases.get(0);
|
||||
assertThat(aliasMetaData.alias()).isEqualTo(alias);
|
||||
assertThat(aliasMetaData.searchRouting()).isEqualTo("0");
|
||||
assertThat(aliasMetaData.indexRouting()).isEqualTo("0");
|
||||
assertThat(count).isEqualTo(1);
|
||||
|
||||
// cleanup
|
||||
elasticsearchTemplate.removeAlias(aliasQuery);
|
||||
}
|
||||
|
||||
@Test // DATAES-541
|
||||
public void shouldRemoveAlias() {
|
||||
|
||||
// given
|
||||
String aliasName = "test-alias";
|
||||
AliasQuery aliasQuery = new AliasBuilder() //
|
||||
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
|
||||
.withAliasName(aliasName) //
|
||||
.build();
|
||||
|
||||
// when
|
||||
elasticsearchTemplate.addAlias(aliasQuery);
|
||||
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
|
||||
assertThat(aliases).isNotNull();
|
||||
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
|
||||
|
||||
// then
|
||||
elasticsearchTemplate.removeAlias(aliasQuery);
|
||||
aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
|
||||
assertThat(aliases).isEmpty();
|
||||
}
|
||||
|
||||
@Document(indexName = INDEX_2_NAME, replicas = 0, shards = 1)
|
||||
class ResultAggregator {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user