mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-14 08:02:11 +00:00
Add new Elasticsearch client as an alternative to the existing REST client.
Original Pull Request #2160 Closes #1973 (cherry picked from commit c0b26a51f1299fdc20998cc54c82ffbc7c005dae)
This commit is contained in:
parent
0950dd6c7a
commit
a86658c397
@ -31,6 +31,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.convert.GeoConverters;
|
||||
@ -67,9 +68,13 @@ class CriteriaFilterProcessor {
|
||||
for (Criteria chainedCriteria : criteria.getCriteriaChain()) {
|
||||
|
||||
if (chainedCriteria.isOr()) {
|
||||
// todo #1973
|
||||
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
|
||||
queriesForEntries(chainedCriteria).forEach(boolQueryBuilder::should);
|
||||
filterQueries.add(new Query(boolQueryBuilder.build()));
|
||||
} else if (chainedCriteria.isNegating()) {
|
||||
// todo #1973
|
||||
Collection<? extends Query> negatingFilters = buildNegatingFilter(criteria.getField().getName(),
|
||||
criteria.getFilterCriteriaEntries());
|
||||
filterQueries.addAll(negatingFilters);
|
||||
} else {
|
||||
filterQueries.addAll(queriesForEntries(chainedCriteria));
|
||||
}
|
||||
@ -85,11 +90,28 @@ class CriteriaFilterProcessor {
|
||||
BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
|
||||
filterQueries.forEach(boolQueryBuilder::must);
|
||||
BoolQuery boolQuery = boolQueryBuilder.build();
|
||||
return Optional.of(boolQuery._toQuery());
|
||||
return Optional.of(new Query(boolQuery));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Collection<? extends Query> buildNegatingFilter(String fieldName,
|
||||
Set<Criteria.CriteriaEntry> filterCriteriaEntries) {
|
||||
|
||||
List<Query> negationFilters = new ArrayList<>();
|
||||
|
||||
filterCriteriaEntries.forEach(criteriaEntry -> {
|
||||
Optional<Query> query = queryFor(criteriaEntry.getKey(), criteriaEntry.getValue(), fieldName);
|
||||
|
||||
if (query.isPresent()) {
|
||||
BoolQuery negatingFilter = QueryBuilders.bool().mustNot(query.get()).build();
|
||||
negationFilters.add(new Query(negatingFilter));
|
||||
}
|
||||
});
|
||||
|
||||
return negationFilters;
|
||||
}
|
||||
|
||||
private static Collection<? extends Query> queriesForEntries(Criteria criteria) {
|
||||
|
||||
Assert.notNull(criteria.getField(), "criteria must have a field");
|
||||
|
@ -80,8 +80,7 @@ final class DocumentAdapters {
|
||||
|
||||
Explanation explanation = from(hit.explanation());
|
||||
|
||||
// todo #1973 matchedQueries
|
||||
List<String> matchedQueries = null;
|
||||
List<String> matchedQueries = hit.matchedQueries();
|
||||
|
||||
Function<Map<String, JsonData>, EntityAsMap> fromFields = fields -> {
|
||||
StringBuilder sb = new StringBuilder("{");
|
||||
|
@ -106,7 +106,6 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
||||
}
|
||||
|
||||
private boolean isSeqNoConflict(Throwable exception) {
|
||||
// todo #1973 check if this works
|
||||
Integer status = null;
|
||||
String message = null;
|
||||
|
||||
|
@ -34,6 +34,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.data.elasticsearch.BulkFailureException;
|
||||
import org.springframework.data.elasticsearch.client.UnsupportedBackendOperation;
|
||||
import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate;
|
||||
@ -68,6 +70,8 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(ElasticsearchTemplate.class);
|
||||
|
||||
private final ElasticsearchClient client;
|
||||
private final RequestConverter requestConverter;
|
||||
private final ResponseConverter responseConverter;
|
||||
@ -249,7 +253,6 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
||||
client -> client.reindex(reindexRequestES));
|
||||
|
||||
if (reindexResponse.task() == null) {
|
||||
// todo #1973 check behaviour and create issue in ES if necessary
|
||||
throw new UnsupportedBackendOperation("ElasticsearchClient did not return a task id on submit request");
|
||||
}
|
||||
|
||||
@ -447,9 +450,6 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
||||
MultiSearchQueryParameter queryParameter = queryIterator.next();
|
||||
MultiSearchResponseItem<EntityAsMap> responseItem = responseIterator.next();
|
||||
|
||||
// if responseItem kind is Result then responseItem.value is a MultiSearchItem which is derived from
|
||||
// SearchResponse
|
||||
|
||||
if (responseItem.isResult()) {
|
||||
|
||||
Class clazz = queryParameter.clazz;
|
||||
@ -463,7 +463,10 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
||||
|
||||
searchHitsList.add(searchHits);
|
||||
} else {
|
||||
// todo #1973 add failure
|
||||
if (LOGGER.isWarnEnabled()) {
|
||||
LOGGER
|
||||
.warn(String.format("multisearch responsecontains failure: {}", responseItem.failure().error().reason()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,10 +87,6 @@ class HighlightQueryBuilder {
|
||||
builder.boundaryScannerLocale(parameters.getBoundaryScannerLocale());
|
||||
}
|
||||
|
||||
if (parameters.getForceSource()) { // default is false
|
||||
// todo #1973 parameter missing in new client
|
||||
}
|
||||
|
||||
if (StringUtils.hasLength(parameters.getFragmenter())) {
|
||||
builder.fragmenter(highlighterFragmenter(parameters.getFragmenter()));
|
||||
}
|
||||
@ -111,10 +107,6 @@ class HighlightQueryBuilder {
|
||||
builder.order(highlighterOrder(parameters.getOrder()));
|
||||
}
|
||||
|
||||
if (parameters.getPhraseLimit() > -1) {
|
||||
// todo #1973 parameter missing in new client
|
||||
}
|
||||
|
||||
if (parameters.getPreTags().length > 0) {
|
||||
builder.preTags(Arrays.asList(parameters.getPreTags()));
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.client.elc;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.FieldValue;
|
||||
import co.elastic.clients.elasticsearch._types.LatLonGeoLocation;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.IdsQuery;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.MatchAllQuery;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.MatchQuery;
|
||||
import co.elastic.clients.elasticsearch._types.query_dsl.Operator;
|
||||
@ -29,6 +30,7 @@ import co.elastic.clients.util.ObjectBuilder;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
@ -45,6 +47,21 @@ public final class QueryBuilders {
|
||||
|
||||
private QueryBuilders() {}
|
||||
|
||||
public static IdsQuery idsQuery(List<String> ids) {
|
||||
|
||||
Assert.notNull(ids, "ids must not be null");
|
||||
|
||||
return IdsQuery.of(i -> i.values(ids));
|
||||
}
|
||||
|
||||
public static Query idsQueryAsQuery(List<String> ids) {
|
||||
|
||||
Assert.notNull(ids, "ids must not be null");
|
||||
|
||||
Function<Query.Builder, ObjectBuilder<Query>> builder = b -> b.ids(idsQuery(ids));
|
||||
|
||||
return builder.apply(new Query.Builder()).build();
|
||||
}
|
||||
public static MatchQuery matchQuery(String fieldName, String query, @Nullable Operator operator,
|
||||
@Nullable Float boost) {
|
||||
|
||||
|
@ -177,8 +177,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
return Mono.from(execute( //
|
||||
(ClientCallback<Publisher<co.elastic.clients.elasticsearch.core.ReindexResponse>>) client -> client
|
||||
.reindex(reindexRequestES)))
|
||||
.flatMap(response -> (response.task() == null) ? Mono.error( // todo #1973 check behaviour and create issue in
|
||||
// ES if necessary
|
||||
.flatMap(response -> (response.task() == null) ? Mono.error(
|
||||
new UnsupportedBackendOperation("ElasticsearchClient did not return a task id on submit request"))
|
||||
: Mono.just(response.task()));
|
||||
}
|
||||
@ -499,7 +498,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
|
||||
@Override
|
||||
public Query idsQuery(List<String> ids) {
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
return NativeQuery.builder().withQuery(QueryBuilders.idsQueryAsQuery(ids)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,6 +58,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
@ -192,7 +193,7 @@ class RequestConverter {
|
||||
|
||||
if (filterQuery != null) {
|
||||
elasticsearchConverter.updateQuery(filterQuery, parameters.getFilterQueryClass());
|
||||
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getFilter(filterQuery);
|
||||
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getQuery(filterQuery, null);
|
||||
if (esQuery != null) {
|
||||
addActionBuilder.filter(esQuery);
|
||||
|
||||
@ -239,7 +240,8 @@ class RequestConverter {
|
||||
PutMappingRequest.Builder builder = new PutMappingRequest.Builder();
|
||||
builder.index(Arrays.asList(indexCoordinates.getIndexNames()));
|
||||
addPropertiesToMapping(builder, mapping);
|
||||
// TODO #1973 what else to add
|
||||
|
||||
// TODO #2155 what else to add
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@ -374,7 +376,7 @@ class RequestConverter {
|
||||
Query filterQuery = parameters.getFilterQuery();
|
||||
|
||||
if (filterQuery != null) {
|
||||
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getFilter(filterQuery);
|
||||
co.elastic.clients.elasticsearch._types.query_dsl.Query esQuery = getQuery(filterQuery, null);
|
||||
|
||||
if (esQuery != null) {
|
||||
aliasBuilder.filter(esQuery);
|
||||
@ -475,7 +477,7 @@ class RequestConverter {
|
||||
}
|
||||
}
|
||||
|
||||
builder.refresh(refresh(refreshPolicy));
|
||||
builder.refresh(TypeUtils.refresh(refreshPolicy));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
@ -644,9 +646,9 @@ class RequestConverter {
|
||||
builder.timeout(tb -> tb.time(Long.valueOf(bulkOptions.getTimeout().toMillis()).toString() + "ms"));
|
||||
}
|
||||
|
||||
builder.refresh(refresh(refreshPolicy));
|
||||
builder.refresh(TypeUtils.refresh(refreshPolicy));
|
||||
if (bulkOptions.getRefreshPolicy() != null) {
|
||||
builder.refresh(refresh(bulkOptions.getRefreshPolicy()));
|
||||
builder.refresh(TypeUtils.refresh(bulkOptions.getRefreshPolicy()));
|
||||
}
|
||||
|
||||
if (bulkOptions.getWaitForActiveShards() != null) {
|
||||
@ -791,13 +793,13 @@ class RequestConverter {
|
||||
ReindexRequest.Dest dest = reindexRequest.getDest();
|
||||
return d //
|
||||
.index(dest.getIndex().getIndexName()) //
|
||||
.versionType(versionType(dest.getVersionType())) //
|
||||
.opType(opType(dest.getOpType()));
|
||||
.versionType(TypeUtils.versionType(dest.getVersionType())) //
|
||||
.opType(TypeUtils.opType(dest.getOpType()));
|
||||
} //
|
||||
);
|
||||
|
||||
if (reindexRequest.getConflicts() != null) {
|
||||
builder.conflicts(conflicts(reindexRequest.getConflicts()));
|
||||
builder.conflicts(TypeUtils.conflicts(reindexRequest.getConflicts()));
|
||||
}
|
||||
|
||||
ReindexRequest.Script script = reindexRequest.getScript();
|
||||
@ -810,7 +812,7 @@ class RequestConverter {
|
||||
|
||||
if (reindexRequest.getWaitForActiveShards() != null) {
|
||||
builder.waitForActiveShards(wfas -> wfas //
|
||||
.count(waitForActiveShardsCount(reindexRequest.getWaitForActiveShards())));
|
||||
.count(TypeUtils.waitForActiveShardsCount(reindexRequest.getWaitForActiveShards())));
|
||||
}
|
||||
|
||||
builder //
|
||||
@ -835,7 +837,7 @@ class RequestConverter {
|
||||
if (routing != null) {
|
||||
r.routing(routing);
|
||||
}
|
||||
r.refresh(refresh(refreshPolicy));
|
||||
r.refresh(TypeUtils.refresh(refreshPolicy));
|
||||
return r;
|
||||
});
|
||||
}
|
||||
@ -908,7 +910,7 @@ class RequestConverter {
|
||||
.docAsUpsert(query.getDocAsUpsert()) //
|
||||
.ifSeqNo(query.getIfSeqNo() != null ? Long.valueOf(query.getIfSeqNo()) : null) //
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm() != null ? Long.valueOf(query.getIfPrimaryTerm()) : null) //
|
||||
.refresh(refresh(refreshPolicy)) //
|
||||
.refresh(TypeUtils.refresh(refreshPolicy)) //
|
||||
.retryOnConflict(query.getRetryOnConflict()) //
|
||||
;
|
||||
|
||||
@ -993,7 +995,7 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (updateQuery.getWaitForActiveShards() != null) {
|
||||
ub.waitForActiveShards(w -> w.count(waitForActiveShardsCount(updateQuery.getWaitForActiveShards())));
|
||||
ub.waitForActiveShards(w -> w.count(TypeUtils.waitForActiveShardsCount(updateQuery.getWaitForActiveShards())));
|
||||
}
|
||||
|
||||
return ub;
|
||||
@ -1048,12 +1050,12 @@ class RequestConverter {
|
||||
mrb.searches(sb -> sb //
|
||||
.header(h -> h //
|
||||
.index(param.index.getIndexName()) //
|
||||
// todo #1973 add remaining flags for header
|
||||
// todo #2156 add remaining flags for header
|
||||
) //
|
||||
.body(bb -> bb //
|
||||
.query(getQuery(param.query, param.clazz))//
|
||||
// #1973 seq_no_primary_term and version not available in client ES issue 161
|
||||
// todo #1973 add remaining flags for body
|
||||
// todo #2138 seq_no_primary_term and version not available in client ES issue 161
|
||||
// todo #2156 add remaining flags for body
|
||||
) //
|
||||
);
|
||||
});
|
||||
@ -1101,7 +1103,7 @@ class RequestConverter {
|
||||
}
|
||||
|
||||
if (query.getIndicesOptions() != null) {
|
||||
// todo #1973 indices options
|
||||
// new Elasticsearch client does not support the old Indices options, need to be adapted
|
||||
}
|
||||
|
||||
if (query.isLimiting()) {
|
||||
@ -1116,7 +1118,7 @@ class RequestConverter {
|
||||
builder.preference(query.getPreference());
|
||||
}
|
||||
|
||||
// todo #1973 searchType
|
||||
builder.searchType(searchType(query.getSearchType()));
|
||||
|
||||
if (query.getSort() != null) {
|
||||
List<SortOptions> sortOptions = getSortOptions(query.getSort(), persistentEntity);
|
||||
@ -1144,7 +1146,7 @@ class RequestConverter {
|
||||
builder.routing(query.getRoute());
|
||||
}
|
||||
|
||||
// todo #1973 timeout
|
||||
builder.timeout(timeStringMs(query.getTimeout()));
|
||||
|
||||
if (query.getExplain()) {
|
||||
builder.explain(true);
|
||||
@ -1158,7 +1160,7 @@ class RequestConverter {
|
||||
builder.rescore(getRescore(rescorerQuery));
|
||||
});
|
||||
|
||||
// todo #1973 request cache
|
||||
builder.requestCache(query.getRequestCache());
|
||||
|
||||
if (!query.getRuntimeFields().isEmpty()) {
|
||||
|
||||
@ -1183,6 +1185,15 @@ class RequestConverter {
|
||||
// limit the number of documents in a batch
|
||||
builder.size(500);
|
||||
}
|
||||
|
||||
if (!isEmpty(query.getIndicesBoost())) {
|
||||
Map<String, Double> boosts = new LinkedHashMap<>();
|
||||
query.getIndicesBoost().forEach(indexBoost -> {
|
||||
boosts.put(indexBoost.getIndexName(), (double) indexBoost.getBoost());
|
||||
});
|
||||
// noinspection unchecked
|
||||
builder.indicesBoost(boosts);
|
||||
}
|
||||
}
|
||||
|
||||
private Rescore getRescore(RescorerQuery rescorerQuery) {
|
||||
@ -1190,7 +1201,7 @@ class RequestConverter {
|
||||
return Rescore.of(r -> r //
|
||||
.query(rq -> rq //
|
||||
.query(getQuery(rescorerQuery.getQuery(), null)) //
|
||||
.scoreMode(scoreMode(rescorerQuery.getScoreMode())) //
|
||||
.scoreMode(TypeUtils.scoreMode(rescorerQuery.getScoreMode())) //
|
||||
.queryWeight(rescorerQuery.getQueryWeight() != null ? Double.valueOf(rescorerQuery.getQueryWeight()) : 1.0) //
|
||||
.rescoreQueryWeight(
|
||||
rescorerQuery.getRescoreQueryWeight() != null ? Double.valueOf(rescorerQuery.getRescoreQueryWeight())
|
||||
@ -1242,8 +1253,9 @@ class RequestConverter {
|
||||
.geoDistance(gd -> gd //
|
||||
.field(fieldName) //
|
||||
.location(loc -> loc.latlon(QueryBuilders.latLon(geoDistanceOrder.getGeoPoint())))//
|
||||
.distanceType(geoDistanceType(geoDistanceOrder.getDistanceType())).mode(sortMode(finalMode)) //
|
||||
.unit(distanceUnit(geoDistanceOrder.getUnit())) //
|
||||
.distanceType(TypeUtils.geoDistanceType(geoDistanceOrder.getDistanceType()))
|
||||
.mode(TypeUtils.sortMode(finalMode)) //
|
||||
.unit(TypeUtils.distanceUnit(geoDistanceOrder.getUnit())) //
|
||||
.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped())));
|
||||
} else {
|
||||
String missing = (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) ? "_first"
|
||||
@ -1253,10 +1265,10 @@ class RequestConverter {
|
||||
.field(f -> {
|
||||
f.field(fieldName) //
|
||||
.order(sortOrder) //
|
||||
.mode(sortMode(finalMode));
|
||||
.mode(TypeUtils.sortMode(finalMode));
|
||||
|
||||
if (finalUnmappedType != null) {
|
||||
FieldType fieldType = fieldType(finalUnmappedType);
|
||||
FieldType fieldType = TypeUtils.fieldType(finalUnmappedType);
|
||||
|
||||
if (fieldType != null) {
|
||||
f.unmappedType(fieldType);
|
||||
@ -1284,13 +1296,11 @@ class RequestConverter {
|
||||
.collapse(query.getFieldCollapse()) //
|
||||
;
|
||||
|
||||
// todo #1973 indices boost
|
||||
|
||||
if (!isEmpty(query.getAggregations())) {
|
||||
builder.aggregations(query.getAggregations());
|
||||
}
|
||||
|
||||
// todo #1973 searchExt
|
||||
// todo #2150 searchExt, currently not supported by the new client
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -1463,12 +1473,6 @@ class RequestConverter {
|
||||
return versionType != null ? versionType : VersionType.External;
|
||||
}
|
||||
|
||||
private co.elastic.clients.elasticsearch._types.query_dsl.Query getFilter(Query filterQuery) {
|
||||
// TODO #1973 add filter query
|
||||
|
||||
throw new UnsupportedOperationException("not implemented");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SourceConfig getSourceConfig(Query query) {
|
||||
|
||||
|
@ -116,7 +116,7 @@ class SearchDocumentResponseBuilder {
|
||||
ElasticsearchAggregations aggregationsContainer = aggregations != null ? new ElasticsearchAggregations(aggregations)
|
||||
: null;
|
||||
|
||||
// todo #1973
|
||||
// todo #2154
|
||||
Suggest suggest = null;
|
||||
|
||||
return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments,
|
||||
|
@ -15,15 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.client.elc;
|
||||
|
||||
import co.elastic.clients.elasticsearch._types.Conflicts;
|
||||
import co.elastic.clients.elasticsearch._types.DistanceUnit;
|
||||
import co.elastic.clients.elasticsearch._types.GeoDistanceType;
|
||||
import co.elastic.clients.elasticsearch._types.OpType;
|
||||
import co.elastic.clients.elasticsearch._types.Refresh;
|
||||
import co.elastic.clients.elasticsearch._types.Result;
|
||||
import co.elastic.clients.elasticsearch._types.SortMode;
|
||||
import co.elastic.clients.elasticsearch._types.Time;
|
||||
import co.elastic.clients.elasticsearch._types.VersionType;
|
||||
import co.elastic.clients.elasticsearch._types.*;
|
||||
import co.elastic.clients.elasticsearch._types.mapping.FieldType;
|
||||
import co.elastic.clients.elasticsearch.core.search.BoundaryScanner;
|
||||
import co.elastic.clients.elasticsearch.core.search.BuiltinHighlighterType;
|
||||
@ -40,6 +32,7 @@ import org.springframework.data.elasticsearch.core.RefreshPolicy;
|
||||
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.Order;
|
||||
import org.springframework.data.elasticsearch.core.query.Query;
|
||||
import org.springframework.data.elasticsearch.core.query.RescorerQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.UpdateResponse;
|
||||
import org.springframework.data.elasticsearch.core.reindex.ReindexRequest;
|
||||
@ -298,6 +291,23 @@ final class TypeUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static SearchType searchType(@Nullable Query.SearchType searchType) {
|
||||
|
||||
if (searchType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (searchType) {
|
||||
case QUERY_THEN_FETCH:
|
||||
return SearchType.QueryThenFetch;
|
||||
case DFS_QUERY_THEN_FETCH:
|
||||
return SearchType.DfsQueryThenFetch;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static SortMode sortMode(Order.Mode mode) {
|
||||
|
||||
@ -325,6 +335,16 @@ final class TypeUtils {
|
||||
return Time.of(t -> t.time(duration.toMillis() + "ms"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static String timeStringMs(@Nullable Duration duration) {
|
||||
|
||||
if (duration == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return duration.toMillis() + "ms";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static VersionType versionType(
|
||||
@Nullable org.springframework.data.elasticsearch.annotations.Document.VersionType versionType) {
|
||||
|
@ -277,8 +277,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
*/
|
||||
protected Mono<GetResult> doGet(GetRequest request) {
|
||||
|
||||
return Mono.from(execute(client -> client.get(request))) //
|
||||
.onErrorResume(NoSuchIndexException.class, it -> Mono.empty());
|
||||
return Mono.from(execute(client -> client.get(request)));
|
||||
}
|
||||
|
||||
protected Mono<String> doDeleteById(String id, @Nullable String routing, IndexCoordinates index) {
|
||||
@ -633,8 +632,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
QUERY_LOGGER.debug(String.format("Executing doCount: %s", request));
|
||||
}
|
||||
|
||||
return Mono.from(execute(client -> client.count(request))) //
|
||||
.onErrorResume(NoSuchIndexException.class, it -> Mono.just(0L));
|
||||
return Mono.from(execute(client -> client.count(request)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,8 @@ import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* class that holds explanations returned from an Elasticsearch search.
|
||||
* class that holds explanations returned from an Elasticsearch search. Note: the new Elasticsearch client does not
|
||||
* return the match property in search hits anymore, probably because a returned hit always is a match.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
|
@ -71,6 +71,7 @@ public class BaseQuery implements Query {
|
||||
@Nullable protected Boolean requestCache;
|
||||
protected List<IdWithRouting> idsWithRouting = Collections.emptyList();
|
||||
protected final List<RuntimeField> runtimeFields = new ArrayList<>();
|
||||
@Nullable protected List<IndexBoost> indicesBoost;
|
||||
|
||||
public BaseQuery() {}
|
||||
|
||||
@ -88,7 +89,7 @@ public class BaseQuery implements Query {
|
||||
this.fields = builder.getFields();
|
||||
this.highlightQuery = builder.highlightQuery;
|
||||
this.route = builder.getRoute();
|
||||
// #1973 add the other fields to the builder
|
||||
this.indicesBoost = builder.getIndicesBoost();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -433,4 +434,10 @@ public class BaseQuery implements Query {
|
||||
public List<RuntimeField> getRuntimeFields() {
|
||||
return runtimeFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<IndexBoost> getIndicesBoost() {
|
||||
return indicesBoost;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
private List<String> fields = new ArrayList<>();
|
||||
@Nullable protected HighlightQuery highlightQuery;
|
||||
@Nullable private String route;
|
||||
@Nullable private List<IndexBoost> indicesBoost;
|
||||
|
||||
@Nullable
|
||||
public Pageable getPageable() {
|
||||
@ -104,6 +105,11 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
return route;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<IndexBoost> getIndicesBoost() {
|
||||
return indicesBoost;
|
||||
}
|
||||
|
||||
public SELF withPageable(Pageable pageable) {
|
||||
this.pageable = pageable;
|
||||
return self();
|
||||
@ -178,6 +184,16 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF withIndicesBoost(List<IndexBoost> indicesBoost) {
|
||||
this.indicesBoost = indicesBoost;
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF withIndicesBoost(IndexBoost... indicesBoost) {
|
||||
this.indicesBoost = Arrays.asList(indicesBoost);
|
||||
return self();
|
||||
}
|
||||
|
||||
public abstract Q build();
|
||||
|
||||
private SELF self() {
|
||||
|
@ -55,7 +55,6 @@ public class NativeSearchQuery extends BaseQuery {
|
||||
@Nullable private List<PipelineAggregationBuilder> pipelineAggregations;
|
||||
@Nullable private HighlightBuilder highlightBuilder;
|
||||
@Nullable private HighlightBuilder.Field[] highlightFields;
|
||||
@Nullable private List<IndexBoost> indicesBoost;
|
||||
@Nullable private SearchTemplateRequestBuilder searchTemplate;
|
||||
@Nullable private SuggestBuilder suggestBuilder;
|
||||
@Nullable private List<SearchExtBuilder> searchExtBuilders;
|
||||
@ -182,11 +181,6 @@ public class NativeSearchQuery extends BaseQuery {
|
||||
this.pipelineAggregations = pipelineAggregationBuilders;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<IndexBoost> getIndicesBoost() {
|
||||
return indicesBoost;
|
||||
}
|
||||
|
||||
public void setIndicesBoost(List<IndexBoost> indicesBoost) {
|
||||
this.indicesBoost = indicesBoost;
|
||||
}
|
||||
|
@ -63,7 +63,6 @@ public class NativeSearchQueryBuilder extends BaseQueryBuilder<NativeSearchQuery
|
||||
@Nullable private List<HighlightBuilder.Field> highlightFields = new ArrayList<>();
|
||||
@Nullable protected List<String> storedFields;
|
||||
@Nullable private CollapseBuilder collapseBuilder;
|
||||
@Nullable private List<IndexBoost> indicesBoost = new ArrayList<>();
|
||||
@Nullable private SearchTemplateRequestBuilder searchTemplateBuilder;
|
||||
@Nullable private SearchType searchType;
|
||||
@Nullable private Boolean trackTotalHits;
|
||||
@ -194,19 +193,6 @@ public class NativeSearchQueryBuilder extends BaseQueryBuilder<NativeSearchQuery
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder withIndicesBoost(Collection<IndexBoost> indicesBoost) {
|
||||
this.indicesBoost.addAll(indicesBoost);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
public NativeSearchQueryBuilder withIndicesBoost(IndexBoost... indicesBoost) {
|
||||
Collections.addAll(this.indicesBoost, indicesBoost);
|
||||
return this;
|
||||
}
|
||||
|
||||
public NativeSearchQueryBuilder withSearchTemplate(SearchTemplateRequestBuilder searchTemplateBuilder) {
|
||||
this.searchTemplateBuilder = searchTemplateBuilder;
|
||||
return this;
|
||||
@ -290,10 +276,6 @@ public class NativeSearchQueryBuilder extends BaseQueryBuilder<NativeSearchQuery
|
||||
nativeSearchQuery.setStoredFields(storedFields);
|
||||
}
|
||||
|
||||
if (indicesBoost != null) {
|
||||
nativeSearchQuery.setIndicesBoost(indicesBoost);
|
||||
}
|
||||
|
||||
if (searchTemplateBuilder != null) {
|
||||
nativeSearchQuery.setSearchTemplate(searchTemplateBuilder);
|
||||
}
|
||||
|
@ -433,6 +433,12 @@ public interface Query {
|
||||
*/
|
||||
List<RuntimeField> getRuntimeFields();
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
@Nullable
|
||||
List<IndexBoost> getIndicesBoost();
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
*/
|
||||
|
@ -1,2 +1,2 @@
|
||||
version.spring-data-elasticsearch=${project.version}
|
||||
version.elasticsearch-client=${elasticsearch}
|
||||
version.elasticsearch-client=${elasticsearch-rhlc}
|
||||
|
@ -16,7 +16,7 @@
|
||||
package org.springframework.data.elasticsearch;
|
||||
|
||||
/**
|
||||
* TODO #1973 remove when the new Elasticsearch client is fully working
|
||||
* TODO remove when the new Elasticsearch client is fully working
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
|
@ -20,12 +20,15 @@ import co.elastic.clients.json.JsonData;
|
||||
import co.elastic.clients.json.JsonpMapper;
|
||||
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.assertj.core.api.SoftAssertions;
|
||||
import org.assertj.core.data.Offset;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.elasticsearch.core.document.Explanation;
|
||||
import org.springframework.data.elasticsearch.core.document.SearchDocument;
|
||||
|
||||
/**
|
||||
@ -106,4 +109,53 @@ class DocumentAdaptersUnitTests {
|
||||
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // #725 #1973
|
||||
@DisplayName("should adapt returned explanations")
|
||||
void shouldAdaptReturnedExplanations() {
|
||||
|
||||
Hit<EntityAsMap> searchHit = new Hit.Builder<EntityAsMap>() //
|
||||
.index("index") //
|
||||
.id("42") //
|
||||
.explanation(eb -> eb //
|
||||
.value(3.14f) //
|
||||
.description("explanation 3.14") //
|
||||
.details(edb -> edb.description("explanation noMatch").value(0f)))
|
||||
.build();
|
||||
|
||||
SearchDocument searchDocument = DocumentAdapters.from(searchHit, jsonpMapper);
|
||||
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
Explanation explanation = searchDocument.getExplanation();
|
||||
softly.assertThat(explanation).isNotNull();
|
||||
softly.assertThat(explanation.isMatch()).isTrue();
|
||||
softly.assertThat(explanation.getValue()).isCloseTo(3.14, Offset.offset(0.001));
|
||||
softly.assertThat(explanation.getDescription()).isEqualTo("explanation 3.14");
|
||||
List<Explanation> details = explanation.getDetails();
|
||||
softly.assertThat(details)
|
||||
.containsExactly(new Explanation(null, 0.0, "explanation noMatch", Collections.emptyList()));
|
||||
softly.assertAll();
|
||||
}
|
||||
|
||||
@Test // DATAES-979 #1973
|
||||
@DisplayName("should adapt returned matched queries")
|
||||
void shouldAdaptReturnedMatchedQueries() {
|
||||
|
||||
Hit<EntityAsMap> searchHit = new Hit.Builder<EntityAsMap>() //
|
||||
.index("index") //
|
||||
.id("42") //
|
||||
.matchedQueries("query1", "query2") //
|
||||
.build();
|
||||
|
||||
SearchDocument searchDocument = DocumentAdapters.from(searchHit, jsonpMapper);
|
||||
|
||||
SoftAssertions softly = new SoftAssertions();
|
||||
|
||||
List<String> matchedQueries = searchDocument.getMatchedQueries();
|
||||
softly.assertThat(matchedQueries).isNotNull();
|
||||
softly.assertThat(matchedQueries).hasSize(2);
|
||||
softly.assertThat(matchedQueries).isEqualTo(Arrays.asList("query1", "query2"));
|
||||
softly.assertAll();
|
||||
}
|
||||
}
|
||||
|
@ -1617,7 +1617,7 @@ public abstract class ElasticsearchIntegrationTests implements NewElasticsearchC
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient",
|
||||
disabledReason = "todo #1973 can't check response, open ES issue 161 that does not allow seqno")
|
||||
disabledReason = "todo #2138 can't check response, open ES issue 161 that does not allow seqno")
|
||||
// and version to be set in the request
|
||||
@Test // DATAES-487
|
||||
public void shouldReturnSameEntityForMultiSearch() {
|
||||
@ -1642,7 +1642,7 @@ public abstract class ElasticsearchIntegrationTests implements NewElasticsearchC
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient",
|
||||
disabledReason = "todo #1973 can't check response, open ES issue 161 that does not allow seqno")
|
||||
disabledReason = "todo #2138 can't check response, open ES issue 161 that does not allow seqno")
|
||||
// and version to be set in the request
|
||||
@Test // DATAES-487
|
||||
public void shouldReturnDifferentEntityForMultiSearch() {
|
||||
@ -3070,7 +3070,7 @@ public abstract class ElasticsearchIntegrationTests implements NewElasticsearchC
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient",
|
||||
disabledReason = "todo #1973 can't check response, open ES issue 161 that does not allow seqno")
|
||||
disabledReason = "todo #2138 can't check response, open ES issue 161 that does not allow seqno")
|
||||
// and version to be set in the request
|
||||
@Test // DATAES-799
|
||||
void multiSearchShouldReturnSeqNoPrimaryTerm() {
|
||||
|
@ -116,7 +116,7 @@ public abstract class CompletionIntegrationTests implements NewElasticsearchClie
|
||||
operations.bulkIndex(indexQueries, AnnotatedCompletionEntity.class);
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason="todo #1973, ES issue 150")
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason = "todo #2139, ES issue 150")
|
||||
@Test
|
||||
public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() {
|
||||
|
||||
@ -148,7 +148,7 @@ public abstract class CompletionIntegrationTests implements NewElasticsearchClie
|
||||
operations.get("1", CompletionEntity.class);
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason="todo #1973, ES issue 150")
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason = "todo #2139, ES issue 150")
|
||||
@Test
|
||||
public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEntity() {
|
||||
|
||||
@ -172,7 +172,7 @@ public abstract class CompletionIntegrationTests implements NewElasticsearchClie
|
||||
assertThat(options.get(1).getText()).isIn("Marchand", "Mohsin");
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason="todo #1973, ES issue 150")
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason = "todo #2139, ES 1issue 150")
|
||||
@Test
|
||||
public void shouldFindSuggestionsWithWeightsForGivenCriteriaQueryUsingAnnotatedCompletionEntity() {
|
||||
|
||||
|
@ -67,7 +67,7 @@ public abstract class ReactiveSuggestIntegrationTests implements NewElasticsearc
|
||||
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete().block();
|
||||
}
|
||||
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason="todo #1973, ES issue 150")
|
||||
@DisabledIf(value = "newElasticsearchClient", disabledReason = "todo #2139, ES issue 150")
|
||||
@Test // #1302
|
||||
@DisplayName("should find suggestions for given prefix completion")
|
||||
void shouldFindSuggestionsForGivenPrefixCompletion() {
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2022 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.repository.support;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchTemplateConfiguration;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.4
|
||||
*/
|
||||
@ContextConfiguration(classes = { SimpleReactiveElasticsearchRepositoryELCIntegrationTests.Config.class })
|
||||
public class SimpleReactiveElasticsearchRepositoryELCIntegrationTests
|
||||
extends SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
@Import({ ReactiveElasticsearchTemplateConfiguration.class })
|
||||
@EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
|
||||
static class Config {
|
||||
@Bean
|
||||
IndexNameProvider indexNameProvider() {
|
||||
return new IndexNameProvider("simple-reactive-repository");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2022 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.repository.support;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
@ContextConfiguration(classes = { SimpleReactiveElasticsearchRepositoryERHLCIntegrationTests.Config.class })
|
||||
public class SimpleReactiveElasticsearchRepositoryERHLCIntegrationTests
|
||||
extends SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
||||
|
||||
@Configuration
|
||||
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
|
||||
@EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
|
||||
static class Config {
|
||||
@Bean
|
||||
IndexNameProvider indexNameProvider() {
|
||||
return new IndexNameProvider("simple-reactive-repository-es7");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -16,81 +16,68 @@
|
||||
package org.springframework.data.elasticsearch.repository.support;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
|
||||
import static org.springframework.data.elasticsearch.core.query.Query.*;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Long;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.elasticsearch.RestStatusException;
|
||||
import org.springframework.data.elasticsearch.NoSuchIndexException;
|
||||
import org.springframework.data.elasticsearch.annotations.CountQuery;
|
||||
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.Highlight;
|
||||
import org.springframework.data.elasticsearch.annotations.HighlightField;
|
||||
import org.springframework.data.elasticsearch.annotations.Query;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.SearchHit;
|
||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
|
||||
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
// todo #1973 test for both clients
|
||||
@SpringIntegrationTest
|
||||
@ContextConfiguration(classes = { SimpleReactiveElasticsearchRepositoryTests.Config.class })
|
||||
class SimpleReactiveElasticsearchRepositoryTests {
|
||||
|
||||
@Configuration
|
||||
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
|
||||
@EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
|
||||
static class Config {}
|
||||
|
||||
static final String INDEX = "test-index-sample-simple-reactive";
|
||||
abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
||||
|
||||
@Autowired ReactiveElasticsearchOperations operations;
|
||||
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||
@Autowired ReactiveSampleEntityRepository repository;
|
||||
|
||||
@Autowired private IndexNameProvider indexNameProvider;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
operations.indexOps(IndexCoordinates.of(INDEX)).delete().block();
|
||||
void before() {
|
||||
indexNameProvider.increment();
|
||||
operations.indexOps(SampleEntity.class).createWithMapping().block();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void after() {
|
||||
operations.indexOps(IndexCoordinates.of(INDEX)).delete().block();
|
||||
@Test
|
||||
@org.junit.jupiter.api.Order(Integer.MAX_VALUE)
|
||||
public void cleanup() {
|
||||
operations.indexOps(IndexCoordinates.of(indexNameProvider.getPrefix() + "*")).delete().block();
|
||||
}
|
||||
|
||||
@Test // DATAES-519
|
||||
@ -104,7 +91,7 @@ class SimpleReactiveElasticsearchRepositoryTests {
|
||||
}
|
||||
|
||||
private Mono<Boolean> documentWithIdExistsInIndex(String id) {
|
||||
return operations.exists(id, IndexCoordinates.of(INDEX));
|
||||
return operations.exists(id, IndexCoordinates.of(indexNameProvider.indexName()));
|
||||
}
|
||||
|
||||
@Test // DATAES-519
|
||||
@ -122,9 +109,12 @@ class SimpleReactiveElasticsearchRepositoryTests {
|
||||
|
||||
@Test // DATAES-519, DATAES-767, DATAES-822
|
||||
void findByIdShouldErrorIfIndexDoesNotExist() {
|
||||
|
||||
operations.indexOps(SampleEntity.class).delete().block();
|
||||
repository.findById("id-two") //
|
||||
.as(StepVerifier::create) //
|
||||
.expectError(RestStatusException.class);
|
||||
.expectError(NoSuchIndexException.class) //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAES-519
|
||||
@ -268,9 +258,12 @@ class SimpleReactiveElasticsearchRepositoryTests {
|
||||
|
||||
@Test // DATAES-519, DATAES-767, DATAES-822
|
||||
void countShouldErrorWhenIndexDoesNotExist() {
|
||||
|
||||
operations.indexOps(SampleEntity.class).delete().block();
|
||||
repository.count() //
|
||||
.as(StepVerifier::create) //
|
||||
.expectError(RestStatusException.class);
|
||||
.expectError(NoSuchIndexException.class) //
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test // DATAES-519
|
||||
@ -596,7 +589,7 @@ class SimpleReactiveElasticsearchRepositoryTests {
|
||||
}
|
||||
|
||||
Mono<Void> bulkIndex(SampleEntity... entities) {
|
||||
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then();
|
||||
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(indexNameProvider.indexName())).then();
|
||||
}
|
||||
|
||||
interface ReactiveSampleEntityRepository extends ReactiveCrudRepository<SampleEntity, String> {
|
||||
@ -636,14 +629,14 @@ class SimpleReactiveElasticsearchRepositoryTests {
|
||||
Mono<Long> retrieveCountByText(String message);
|
||||
}
|
||||
|
||||
@Document(indexName = INDEX)
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||
static class SampleEntity {
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String type;
|
||||
@Field(type = FieldType.Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Field(type = FieldType.Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
@Nullable private boolean available;
|
||||
@Nullable
|
Loading…
x
Reference in New Issue
Block a user