mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-23 20:42:11 +00:00
Add SpEL support for highlight query and source filter.
Original Pull Request #2853 Closes #2852
This commit is contained in:
parent
96185f94ef
commit
6af099ea34
@ -30,12 +30,12 @@ import org.springframework.lang.Nullable;
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A representation of a Elasticsearch document as extended {@link StringObjectMap Map}. All iterators preserve original
|
* A representation of an Elasticsearch document as extended {@link StringObjectMap Map}. All iterators preserve original
|
||||||
* insertion order.
|
* insertion order.
|
||||||
* <p>
|
* <p>
|
||||||
* Document does not allow {@code null} keys. It allows {@literal null} values.
|
* Document does not allow {@code null} keys. It allows {@literal null} values.
|
||||||
* <p>
|
* <p>
|
||||||
* Implementing classes can bei either mutable or immutable. In case a subclass is immutable, its methods may throw
|
* Implementing classes can be either mutable or immutable. In case a subclass is immutable, its methods may throw
|
||||||
* {@link UnsupportedOperationException} when calling modifying methods.
|
* {@link UnsupportedOperationException} when calling modifying methods.
|
||||||
*
|
*
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
|
@ -25,6 +25,7 @@ import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
|||||||
import org.springframework.data.elasticsearch.core.query.Query;
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||||
import org.springframework.data.repository.query.QueryMethod;
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.query.RepositoryQuery;
|
import org.springframework.data.repository.query.RepositoryQuery;
|
||||||
import org.springframework.data.repository.query.ResultProcessor;
|
import org.springframework.data.repository.query.ResultProcessor;
|
||||||
import org.springframework.data.util.StreamUtils;
|
import org.springframework.data.util.StreamUtils;
|
||||||
@ -47,12 +48,15 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
|
|||||||
protected ElasticsearchQueryMethod queryMethod;
|
protected ElasticsearchQueryMethod queryMethod;
|
||||||
protected final ElasticsearchOperations elasticsearchOperations;
|
protected final ElasticsearchOperations elasticsearchOperations;
|
||||||
protected final ElasticsearchConverter elasticsearchConverter;
|
protected final ElasticsearchConverter elasticsearchConverter;
|
||||||
|
protected final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||||
|
|
||||||
public AbstractElasticsearchRepositoryQuery(ElasticsearchQueryMethod queryMethod,
|
public AbstractElasticsearchRepositoryQuery(ElasticsearchQueryMethod queryMethod,
|
||||||
ElasticsearchOperations elasticsearchOperations) {
|
ElasticsearchOperations elasticsearchOperations,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
this.queryMethod = queryMethod;
|
this.queryMethod = queryMethod;
|
||||||
this.elasticsearchOperations = elasticsearchOperations;
|
this.elasticsearchOperations = elasticsearchOperations;
|
||||||
this.elasticsearchConverter = elasticsearchOperations.getElasticsearchConverter();
|
this.elasticsearchConverter = elasticsearchOperations.getElasticsearchConverter();
|
||||||
|
this.evaluationContextProvider = evaluationContextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -128,7 +132,8 @@ public abstract class AbstractElasticsearchRepositoryQuery implements Repository
|
|||||||
var query = createQuery(parameterAccessor);
|
var query = createQuery(parameterAccessor);
|
||||||
Assert.notNull(query, "unsupported query");
|
Assert.notNull(query, "unsupported query");
|
||||||
|
|
||||||
queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter());
|
queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter(),
|
||||||
|
evaluationContextProvider);
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import org.springframework.data.elasticsearch.repository.query.ReactiveElasticse
|
|||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.repository.query.ParameterAccessor;
|
import org.springframework.data.repository.query.ParameterAccessor;
|
||||||
import org.springframework.data.repository.query.QueryMethod;
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.query.RepositoryQuery;
|
import org.springframework.data.repository.query.RepositoryQuery;
|
||||||
import org.springframework.data.repository.query.ResultProcessor;
|
import org.springframework.data.repository.query.ResultProcessor;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
@ -50,12 +51,15 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
|
|||||||
|
|
||||||
protected final ReactiveElasticsearchQueryMethod queryMethod;
|
protected final ReactiveElasticsearchQueryMethod queryMethod;
|
||||||
private final ReactiveElasticsearchOperations elasticsearchOperations;
|
private final ReactiveElasticsearchOperations elasticsearchOperations;
|
||||||
|
protected final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||||
|
|
||||||
AbstractReactiveElasticsearchRepositoryQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
AbstractReactiveElasticsearchRepositoryQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
||||||
ReactiveElasticsearchOperations elasticsearchOperations) {
|
ReactiveElasticsearchOperations elasticsearchOperations,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
|
||||||
this.queryMethod = queryMethod;
|
this.queryMethod = queryMethod;
|
||||||
this.elasticsearchOperations = elasticsearchOperations;
|
this.elasticsearchOperations = elasticsearchOperations;
|
||||||
|
this.evaluationContextProvider = evaluationContextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -96,7 +100,8 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor
|
|||||||
var query = createQuery(parameterAccessor);
|
var query = createQuery(parameterAccessor);
|
||||||
Assert.notNull(query, "unsupported query");
|
Assert.notNull(query, "unsupported query");
|
||||||
|
|
||||||
queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter());
|
queryMethod.addMethodParameter(query, parameterAccessor, elasticsearchOperations.getElasticsearchConverter(),
|
||||||
|
evaluationContextProvider);
|
||||||
|
|
||||||
String indexName = queryMethod.getEntityInformation().getIndexName();
|
String indexName = queryMethod.getEntityInformation().getIndexName();
|
||||||
IndexCoordinates index = IndexCoordinates.of(indexName);
|
IndexCoordinates index = IndexCoordinates.of(indexName);
|
||||||
|
@ -18,11 +18,9 @@ package org.springframework.data.elasticsearch.repository.query;
|
|||||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.Query;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.RuntimeField;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.ScriptedField;
|
|
||||||
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
|
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,14 +32,16 @@ import org.springframework.data.repository.query.parser.PartTree;
|
|||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Rasmus Faber-Espensen
|
* @author Rasmus Faber-Espensen
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Haibo Liu
|
||||||
*/
|
*/
|
||||||
public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
|
public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
|
||||||
|
|
||||||
private final PartTree tree;
|
private final PartTree tree;
|
||||||
private final MappingContext<?, ElasticsearchPersistentProperty> mappingContext;
|
private final MappingContext<?, ElasticsearchPersistentProperty> mappingContext;
|
||||||
|
|
||||||
public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOperations elasticsearchOperations) {
|
public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOperations elasticsearchOperations,
|
||||||
super(method, elasticsearchOperations);
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
super(method, elasticsearchOperations, evaluationContextProvider);
|
||||||
this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
|
this.tree = new PartTree(queryMethod.getName(), queryMethod.getResultProcessor().getReturnedType().getDomainType());
|
||||||
this.mappingContext = elasticsearchConverter.getMappingContext();
|
this.mappingContext = elasticsearchConverter.getMappingContext();
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||||
import org.springframework.data.elasticsearch.annotations.Highlight;
|
import org.springframework.data.elasticsearch.annotations.Highlight;
|
||||||
import org.springframework.data.elasticsearch.annotations.Query;
|
import org.springframework.data.elasticsearch.annotations.Query;
|
||||||
@ -41,13 +42,13 @@ import org.springframework.data.elasticsearch.core.query.HighlightQuery;
|
|||||||
import org.springframework.data.elasticsearch.core.query.RuntimeField;
|
import org.springframework.data.elasticsearch.core.query.RuntimeField;
|
||||||
import org.springframework.data.elasticsearch.core.query.ScriptedField;
|
import org.springframework.data.elasticsearch.core.query.ScriptedField;
|
||||||
import org.springframework.data.elasticsearch.core.query.SourceFilter;
|
import org.springframework.data.elasticsearch.core.query.SourceFilter;
|
||||||
import org.springframework.data.elasticsearch.repository.support.StringQueryUtil;
|
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.data.projection.ProjectionFactory;
|
import org.springframework.data.projection.ProjectionFactory;
|
||||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||||
import org.springframework.data.repository.query.ParameterAccessor;
|
|
||||||
import org.springframework.data.repository.query.Parameters;
|
import org.springframework.data.repository.query.Parameters;
|
||||||
import org.springframework.data.repository.query.QueryMethod;
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.util.QueryExecutionConverters;
|
import org.springframework.data.repository.util.QueryExecutionConverters;
|
||||||
import org.springframework.data.repository.util.ReactiveWrapperConverters;
|
import org.springframework.data.repository.util.ReactiveWrapperConverters;
|
||||||
import org.springframework.data.util.TypeInformation;
|
import org.springframework.data.util.TypeInformation;
|
||||||
@ -146,9 +147,7 @@ public class ElasticsearchQueryMethod extends QueryMethod {
|
|||||||
Assert.isTrue(hasAnnotatedHighlight(), "no Highlight annotation present on " + getName());
|
Assert.isTrue(hasAnnotatedHighlight(), "no Highlight annotation present on " + getName());
|
||||||
Assert.notNull(highlightAnnotation, "highlightAnnotation must not be null");
|
Assert.notNull(highlightAnnotation, "highlightAnnotation must not be null");
|
||||||
|
|
||||||
return new HighlightQuery(
|
return new HighlightQuery(highlightConverter.convert(highlightAnnotation), getDomainClass());
|
||||||
highlightConverter.convert(highlightAnnotation),
|
|
||||||
getDomainClass());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,42 +287,46 @@ public class ElasticsearchQueryMethod extends QueryMethod {
|
|||||||
* @param parameterAccessor the accessor with the query method parameter details
|
* @param parameterAccessor the accessor with the query method parameter details
|
||||||
* @param converter {@link ElasticsearchConverter} needed to convert entity property names to the Elasticsearch field
|
* @param converter {@link ElasticsearchConverter} needed to convert entity property names to the Elasticsearch field
|
||||||
* names and for parameter conversion when the includes or excludes are defined as parameters
|
* names and for parameter conversion when the includes or excludes are defined as parameters
|
||||||
|
* @param evaluationContextProvider to provide an evaluation context for SpEL evaluation
|
||||||
* @return source filter with includes and excludes for a query, {@literal null} when no {@link SourceFilters}
|
* @return source filter with includes and excludes for a query, {@literal null} when no {@link SourceFilters}
|
||||||
* annotation was set on the method.
|
* annotation was set on the method.
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
SourceFilter getSourceFilter(ParameterAccessor parameterAccessor, ElasticsearchConverter converter) {
|
SourceFilter getSourceFilter(ElasticsearchParametersParameterAccessor parameterAccessor,
|
||||||
|
ElasticsearchConverter converter,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
|
||||||
if (sourceFilters == null || (sourceFilters.includes().length == 0 && sourceFilters.excludes().length == 0)) {
|
if (sourceFilters == null || (sourceFilters.includes().length == 0 && sourceFilters.excludes().length == 0)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringQueryUtil stringQueryUtil = new StringQueryUtil(converter.getConversionService());
|
ConversionService conversionService = converter.getConversionService();
|
||||||
FetchSourceFilterBuilder fetchSourceFilterBuilder = new FetchSourceFilterBuilder();
|
FetchSourceFilterBuilder fetchSourceFilterBuilder = new FetchSourceFilterBuilder();
|
||||||
|
|
||||||
if (sourceFilters.includes().length > 0) {
|
if (sourceFilters.includes().length > 0) {
|
||||||
fetchSourceFilterBuilder
|
fetchSourceFilterBuilder.withIncludes(mapParameters(sourceFilters.includes(), parameterAccessor,
|
||||||
.withIncludes(mapParameters(sourceFilters.includes(), parameterAccessor, stringQueryUtil));
|
conversionService, evaluationContextProvider));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFilters.excludes().length > 0) {
|
if (sourceFilters.excludes().length > 0) {
|
||||||
fetchSourceFilterBuilder
|
fetchSourceFilterBuilder.withExcludes(mapParameters(sourceFilters.excludes(), parameterAccessor,
|
||||||
.withExcludes(mapParameters(sourceFilters.excludes(), parameterAccessor, stringQueryUtil));
|
conversionService, evaluationContextProvider));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetchSourceFilterBuilder.build();
|
return fetchSourceFilterBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] mapParameters(String[] source, ParameterAccessor parameterAccessor,
|
private String[] mapParameters(String[] source, ElasticsearchParametersParameterAccessor parameterAccessor,
|
||||||
StringQueryUtil stringQueryUtil) {
|
ConversionService conversionService, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
|
||||||
List<String> fieldNames = new ArrayList<>();
|
List<String> fieldNames = new ArrayList<>();
|
||||||
|
|
||||||
for (String s : source) {
|
for (String s : source) {
|
||||||
|
|
||||||
if (!s.isBlank()) {
|
if (!s.isBlank()) {
|
||||||
String fieldName = stringQueryUtil.replacePlaceholders(s, parameterAccessor);
|
String fieldName = new QueryStringProcessor(s, this, conversionService, evaluationContextProvider)
|
||||||
|
.createQuery(parameterAccessor);
|
||||||
// this could be "[\"foo\",\"bar\"]", must be split
|
// this could be "[\"foo\",\"bar\"]", must be split
|
||||||
if (fieldName.startsWith("[") && fieldName.endsWith("]")) {
|
if (fieldName.startsWith("[") && fieldName.endsWith("]")) {
|
||||||
// noinspection RegExpRedundantEscape
|
// noinspection RegExpRedundantEscape
|
||||||
@ -367,14 +370,16 @@ public class ElasticsearchQueryMethod extends QueryMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addMethodParameter(BaseQuery query, ElasticsearchParametersParameterAccessor parameterAccessor,
|
void addMethodParameter(BaseQuery query, ElasticsearchParametersParameterAccessor parameterAccessor,
|
||||||
ElasticsearchConverter elasticsearchConverter) {
|
ElasticsearchConverter elasticsearchConverter,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
|
||||||
if (hasAnnotatedHighlight()) {
|
if (hasAnnotatedHighlight()) {
|
||||||
query.setHighlightQuery(
|
var highlightQuery = getAnnotatedHighlightQuery(new HighlightConverter(parameterAccessor,
|
||||||
getAnnotatedHighlightQuery(new HighlightConverter(parameterAccessor, elasticsearchConverter)));
|
elasticsearchConverter.getConversionService(), evaluationContextProvider, this));
|
||||||
|
query.setHighlightQuery(highlightQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceFilter = getSourceFilter(parameterAccessor, elasticsearchConverter);
|
var sourceFilter = getSourceFilter(parameterAccessor, elasticsearchConverter, evaluationContextProvider);
|
||||||
if (sourceFilter != null) {
|
if (sourceFilter != null) {
|
||||||
query.addSourceFilter(sourceFilter);
|
query.addSourceFilter(sourceFilter);
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,7 @@ import org.springframework.core.convert.ConversionService;
|
|||||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
import org.springframework.data.elasticsearch.repository.support.StringQueryUtil;
|
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
|
||||||
import org.springframework.data.elasticsearch.repository.support.spel.QueryStringSpELEvaluator;
|
|
||||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -37,17 +36,15 @@ import org.springframework.util.Assert;
|
|||||||
public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQuery {
|
public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQuery {
|
||||||
|
|
||||||
private final String queryString;
|
private final String queryString;
|
||||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
|
||||||
|
|
||||||
public ElasticsearchStringQuery(ElasticsearchQueryMethod queryMethod, ElasticsearchOperations elasticsearchOperations,
|
public ElasticsearchStringQuery(ElasticsearchQueryMethod queryMethod, ElasticsearchOperations elasticsearchOperations,
|
||||||
String queryString, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
String queryString, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
super(queryMethod, elasticsearchOperations);
|
super(queryMethod, elasticsearchOperations, evaluationContextProvider);
|
||||||
|
|
||||||
Assert.notNull(queryString, "Query cannot be empty");
|
Assert.notNull(queryString, "Query cannot be empty");
|
||||||
Assert.notNull(evaluationContextProvider, "ExpressionEvaluationContextProvider must not be null");
|
Assert.notNull(evaluationContextProvider, "ExpressionEvaluationContextProvider must not be null");
|
||||||
|
|
||||||
this.queryString = queryString;
|
this.queryString = queryString;
|
||||||
this.evaluationContextProvider = evaluationContextProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,15 +63,12 @@ public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQue
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
|
protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
|
||||||
|
|
||||||
ConversionService conversionService = elasticsearchOperations.getElasticsearchConverter().getConversionService();
|
ConversionService conversionService = elasticsearchOperations.getElasticsearchConverter().getConversionService();
|
||||||
var replacedString = new StringQueryUtil(conversionService).replacePlaceholders(this.queryString,
|
var processed = new QueryStringProcessor(queryString, queryMethod, conversionService, evaluationContextProvider)
|
||||||
parameterAccessor);
|
.createQuery(parameterAccessor);
|
||||||
var evaluator = new QueryStringSpELEvaluator(replacedString, parameterAccessor, queryMethod,
|
|
||||||
evaluationContextProvider, conversionService);
|
return new StringQuery(processed)
|
||||||
var query = new StringQuery(evaluator.evaluate());
|
.addSort(parameterAccessor.getSort());
|
||||||
query.addSort(parameterAccessor.getSort());
|
|
||||||
return query;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,15 @@ package org.springframework.data.elasticsearch.repository.query;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.data.elasticsearch.core.query.Query;
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
|
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
|
||||||
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
|
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
|
||||||
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
|
import org.springframework.data.elasticsearch.core.query.highlight.HighlightParameters;
|
||||||
import org.springframework.data.elasticsearch.repository.support.StringQueryUtil;
|
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
|
||||||
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,12 +37,24 @@ import org.springframework.util.Assert;
|
|||||||
public class HighlightConverter {
|
public class HighlightConverter {
|
||||||
|
|
||||||
private final ElasticsearchParametersParameterAccessor parameterAccessor;
|
private final ElasticsearchParametersParameterAccessor parameterAccessor;
|
||||||
private final ElasticsearchConverter elasticsearchConverter;
|
private final ConversionService conversionService;
|
||||||
|
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||||
|
private final QueryMethod queryMethod;
|
||||||
|
|
||||||
HighlightConverter(ElasticsearchParametersParameterAccessor parameterAccessor,
|
HighlightConverter(ElasticsearchParametersParameterAccessor parameterAccessor,
|
||||||
ElasticsearchConverter elasticsearchConverter) {
|
ConversionService conversionService,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider,
|
||||||
|
QueryMethod queryMethod) {
|
||||||
|
|
||||||
|
Assert.notNull(parameterAccessor, "parameterAccessor must not be null");
|
||||||
|
Assert.notNull(conversionService, "conversionService must not be null");
|
||||||
|
Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
|
||||||
|
Assert.notNull(queryMethod, "queryMethod must not be null");
|
||||||
|
|
||||||
this.parameterAccessor = parameterAccessor;
|
this.parameterAccessor = parameterAccessor;
|
||||||
this.elasticsearchConverter = elasticsearchConverter;
|
this.conversionService = conversionService;
|
||||||
|
this.evaluationContextProvider = evaluationContextProvider;
|
||||||
|
this.queryMethod = queryMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,10 +72,10 @@ public class HighlightConverter {
|
|||||||
// replace placeholders in highlight query with actual parameters
|
// replace placeholders in highlight query with actual parameters
|
||||||
Query highlightQuery = null;
|
Query highlightQuery = null;
|
||||||
if (!parameters.highlightQuery().value().isEmpty()) {
|
if (!parameters.highlightQuery().value().isEmpty()) {
|
||||||
String rawString = parameters.highlightQuery().value();
|
String rawQuery = parameters.highlightQuery().value();
|
||||||
String queryString = new StringQueryUtil(elasticsearchConverter.getConversionService())
|
String query = new QueryStringProcessor(rawQuery, queryMethod, conversionService, evaluationContextProvider)
|
||||||
.replacePlaceholders(rawString, parameterAccessor);
|
.createQuery(parameterAccessor);
|
||||||
highlightQuery = new StringQuery(queryString);
|
highlightQuery = new StringQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
HighlightParameters highlightParameters = HighlightParameters.builder() //
|
HighlightParameters highlightParameters = HighlightParameters.builder() //
|
||||||
|
@ -19,10 +19,8 @@ import org.springframework.core.convert.ConversionService;
|
|||||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
import org.springframework.data.elasticsearch.repository.support.StringQueryUtil;
|
import org.springframework.data.elasticsearch.repository.support.QueryStringProcessor;
|
||||||
import org.springframework.data.elasticsearch.repository.support.spel.QueryStringSpELEvaluator;
|
|
||||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,16 +35,14 @@ public class ReactiveElasticsearchStringQuery extends AbstractReactiveElasticsea
|
|||||||
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||||
|
|
||||||
public ReactiveElasticsearchStringQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
public ReactiveElasticsearchStringQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
||||||
ReactiveElasticsearchOperations operations, SpelExpressionParser expressionParser,
|
ReactiveElasticsearchOperations operations, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
|
||||||
|
|
||||||
this(queryMethod.getAnnotatedQuery(), queryMethod, operations, expressionParser, evaluationContextProvider);
|
this(queryMethod.getAnnotatedQuery(), queryMethod, operations, evaluationContextProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReactiveElasticsearchStringQuery(String query, ReactiveElasticsearchQueryMethod queryMethod,
|
public ReactiveElasticsearchStringQuery(String query, ReactiveElasticsearchQueryMethod queryMethod,
|
||||||
ReactiveElasticsearchOperations operations, SpelExpressionParser expressionParser,
|
ReactiveElasticsearchOperations operations, QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
super(queryMethod, operations, evaluationContextProvider);
|
||||||
super(queryMethod, operations);
|
|
||||||
|
|
||||||
Assert.notNull(query, "query must not be null");
|
Assert.notNull(query, "query must not be null");
|
||||||
Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
|
Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
|
||||||
@ -57,15 +53,11 @@ public class ReactiveElasticsearchStringQuery extends AbstractReactiveElasticsea
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
|
protected BaseQuery createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
|
||||||
String queryString = new StringQueryUtil(
|
|
||||||
getElasticsearchOperations().getElasticsearchConverter().getConversionService())
|
|
||||||
.replacePlaceholders(this.query, parameterAccessor);
|
|
||||||
|
|
||||||
ConversionService conversionService = getElasticsearchOperations().getElasticsearchConverter()
|
ConversionService conversionService = getElasticsearchOperations().getElasticsearchConverter()
|
||||||
.getConversionService();
|
.getConversionService();
|
||||||
QueryStringSpELEvaluator evaluator = new QueryStringSpELEvaluator(queryString, parameterAccessor, queryMethod,
|
String processed = new QueryStringProcessor(query, queryMethod, conversionService, evaluationContextProvider)
|
||||||
evaluationContextProvider, conversionService);
|
.createQuery(parameterAccessor);
|
||||||
return new StringQuery(evaluator.evaluate());
|
return new StringQuery(processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,12 +19,14 @@ import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperatio
|
|||||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||||
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
|
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.query.ResultProcessor;
|
import org.springframework.data.repository.query.ResultProcessor;
|
||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Haibo Liu
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class ReactivePartTreeElasticsearchQuery extends AbstractReactiveElasticsearchRepositoryQuery {
|
public class ReactivePartTreeElasticsearchQuery extends AbstractReactiveElasticsearchRepositoryQuery {
|
||||||
@ -32,8 +34,9 @@ public class ReactivePartTreeElasticsearchQuery extends AbstractReactiveElastics
|
|||||||
private final PartTree tree;
|
private final PartTree tree;
|
||||||
|
|
||||||
public ReactivePartTreeElasticsearchQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
public ReactivePartTreeElasticsearchQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
||||||
ReactiveElasticsearchOperations elasticsearchOperations) {
|
ReactiveElasticsearchOperations elasticsearchOperations,
|
||||||
super(queryMethod, elasticsearchOperations);
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
super(queryMethod, elasticsearchOperations, evaluationContextProvider);
|
||||||
|
|
||||||
ResultProcessor processor = queryMethod.getResultProcessor();
|
ResultProcessor processor = queryMethod.getResultProcessor();
|
||||||
this.tree = new PartTree(queryMethod.getName(), processor.getReturnedType().getDomainType());
|
this.tree = new PartTree(queryMethod.getName(), processor.getReturnedType().getDomainType());
|
||||||
|
@ -128,7 +128,7 @@ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport {
|
|||||||
return new ElasticsearchStringQuery(queryMethod, elasticsearchOperations, queryMethod.getAnnotatedQuery(),
|
return new ElasticsearchStringQuery(queryMethod, elasticsearchOperations, queryMethod.getAnnotatedQuery(),
|
||||||
evaluationContextProvider);
|
evaluationContextProvider);
|
||||||
}
|
}
|
||||||
return new ElasticsearchPartQuery(queryMethod, elasticsearchOperations);
|
return new ElasticsearchPartQuery(queryMethod, elasticsearchOperations, evaluationContextProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,23 +26,32 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.NumberUtils;
|
import org.springframework.util.NumberUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* To replace the placeholders like `?0`, `?1, `?2` of the query string.
|
||||||
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
* @author Niklas Herder
|
* @author Niklas Herder
|
||||||
* @author Haibo Liu
|
* @author Haibo Liu
|
||||||
*/
|
*/
|
||||||
final public class StringQueryUtil {
|
final public class QueryStringPlaceholderReplacer {
|
||||||
|
|
||||||
private static final Pattern PARAMETER_PLACEHOLDER = Pattern.compile("\\?(\\d+)");
|
private static final Pattern PARAMETER_PLACEHOLDER = Pattern.compile("\\?(\\d+)");
|
||||||
|
|
||||||
private final ConversionService conversionService;
|
private final ConversionService conversionService;
|
||||||
|
|
||||||
public StringQueryUtil(ConversionService conversionService) {
|
public QueryStringPlaceholderReplacer(ConversionService conversionService) {
|
||||||
|
|
||||||
Assert.notNull(conversionService, "conversionService must not be null");
|
Assert.notNull(conversionService, "conversionService must not be null");
|
||||||
|
|
||||||
this.conversionService = ElasticsearchQueryValueConversionService.getInstance(conversionService);
|
this.conversionService = ElasticsearchQueryValueConversionService.getInstance(conversionService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the placeholders of the query string.
|
||||||
|
*
|
||||||
|
* @param input raw query string
|
||||||
|
* @param accessor parameter info
|
||||||
|
* @return a plain string with placeholders replaced
|
||||||
|
*/
|
||||||
public String replacePlaceholders(String input, ParameterAccessor accessor) {
|
public String replacePlaceholders(String input, ParameterAccessor accessor) {
|
||||||
|
|
||||||
Matcher matcher = PARAMETER_PLACEHOLDER.matcher(input);
|
Matcher matcher = PARAMETER_PLACEHOLDER.matcher(input);
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.core.convert.ConversionService;
|
||||||
|
import org.springframework.data.elasticsearch.repository.query.ElasticsearchParametersParameterAccessor;
|
||||||
|
import org.springframework.data.elasticsearch.repository.support.spel.QueryStringSpELEvaluator;
|
||||||
|
import org.springframework.data.repository.query.QueryMethod;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To process query strings with placeholder replacement and SpEL evaluation by {@link QueryStringPlaceholderReplacer}
|
||||||
|
* and {@link QueryStringSpELEvaluator}.
|
||||||
|
*
|
||||||
|
* @since 5.3
|
||||||
|
* @author Haibo Liu
|
||||||
|
*/
|
||||||
|
public class QueryStringProcessor {
|
||||||
|
|
||||||
|
private final String query;
|
||||||
|
private final QueryMethod queryMethod;
|
||||||
|
private final ConversionService conversionService;
|
||||||
|
private final QueryMethodEvaluationContextProvider evaluationContextProvider;
|
||||||
|
|
||||||
|
public QueryStringProcessor(String query, QueryMethod queryMethod, ConversionService conversionService,
|
||||||
|
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||||
|
|
||||||
|
Assert.notNull(query, "query must not be null");
|
||||||
|
Assert.notNull(queryMethod, "queryMethod must not be null");
|
||||||
|
Assert.notNull(conversionService, "conversionService must not be null");
|
||||||
|
Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null");
|
||||||
|
|
||||||
|
this.query = query;
|
||||||
|
this.queryMethod = queryMethod;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
this.evaluationContextProvider = evaluationContextProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the query string with placeholder replacement and SpEL evaluation.
|
||||||
|
*
|
||||||
|
* @param parameterAccessor parameter info
|
||||||
|
* @return processed string
|
||||||
|
*/
|
||||||
|
public String createQuery(ElasticsearchParametersParameterAccessor parameterAccessor) {
|
||||||
|
String queryString = new QueryStringPlaceholderReplacer(conversionService)
|
||||||
|
.replacePlaceholders(query, parameterAccessor);
|
||||||
|
|
||||||
|
QueryStringSpELEvaluator evaluator = new QueryStringSpELEvaluator(queryString, parameterAccessor, queryMethod,
|
||||||
|
evaluationContextProvider, conversionService);
|
||||||
|
return evaluator.evaluate();
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
|||||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
|
import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor;
|
||||||
import org.springframework.data.repository.query.RepositoryQuery;
|
import org.springframework.data.repository.query.RepositoryQuery;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -50,12 +49,11 @@ import org.springframework.util.Assert;
|
|||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Ivan Greene
|
* @author Ivan Greene
|
||||||
* @author Ezequiel Antúnez Camacho
|
* @author Ezequiel Antúnez Camacho
|
||||||
|
* @author Haibo Liu
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class ReactiveElasticsearchRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
public class ReactiveElasticsearchRepositoryFactory extends ReactiveRepositoryFactorySupport {
|
||||||
|
|
||||||
private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
|
|
||||||
|
|
||||||
private final ReactiveElasticsearchOperations operations;
|
private final ReactiveElasticsearchOperations operations;
|
||||||
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
|
||||||
|
|
||||||
@ -163,13 +161,12 @@ public class ReactiveElasticsearchRepositoryFactory extends ReactiveRepositoryFa
|
|||||||
if (namedQueries.hasQuery(namedQueryName)) {
|
if (namedQueries.hasQuery(namedQueryName)) {
|
||||||
String namedQuery = namedQueries.getQuery(namedQueryName);
|
String namedQuery = namedQueries.getQuery(namedQueryName);
|
||||||
|
|
||||||
return new ReactiveElasticsearchStringQuery(namedQuery, queryMethod, operations, EXPRESSION_PARSER,
|
return new ReactiveElasticsearchStringQuery(namedQuery, queryMethod, operations,
|
||||||
evaluationContextProvider);
|
evaluationContextProvider);
|
||||||
} else if (queryMethod.hasAnnotatedQuery()) {
|
} else if (queryMethod.hasAnnotatedQuery()) {
|
||||||
return new ReactiveElasticsearchStringQuery(queryMethod, operations, EXPRESSION_PARSER,
|
return new ReactiveElasticsearchStringQuery(queryMethod, operations, evaluationContextProvider);
|
||||||
evaluationContextProvider);
|
|
||||||
} else {
|
} else {
|
||||||
return new ReactivePartTreeElasticsearchQuery(queryMethod, operations);
|
return new ReactivePartTreeElasticsearchQuery(queryMethod, operations, evaluationContextProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import org.springframework.data.elasticsearch.repository.query.ElasticsearchPart
|
|||||||
import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod;
|
import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod;
|
||||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||||
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,6 +45,7 @@ import org.springframework.lang.Nullable;
|
|||||||
* kept package private.
|
* kept package private.
|
||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
|
* @author Haibo Liu
|
||||||
*/
|
*/
|
||||||
@SpringIntegrationTest
|
@SpringIntegrationTest
|
||||||
public abstract class ElasticsearchPartQueryIntegrationTests {
|
public abstract class ElasticsearchPartQueryIntegrationTests {
|
||||||
@ -647,7 +649,8 @@ public abstract class ElasticsearchPartQueryIntegrationTests {
|
|||||||
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method,
|
ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method,
|
||||||
new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(),
|
new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(),
|
||||||
operations.getElasticsearchConverter().getMappingContext());
|
operations.getElasticsearchConverter().getMappingContext());
|
||||||
ElasticsearchPartQuery partQuery = new ElasticsearchPartQuery(queryMethod, operations);
|
ElasticsearchPartQuery partQuery = new ElasticsearchPartQuery(queryMethod, operations,
|
||||||
|
QueryMethodEvaluationContextProvider.DEFAULT);
|
||||||
Query query = partQuery.createQuery(parameters);
|
Query query = partQuery.createQuery(parameters);
|
||||||
return buildQueryString(query, Book.class);
|
return buildQueryString(query, Book.class);
|
||||||
}
|
}
|
||||||
|
@ -1740,6 +1740,26 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
assertThat(highlightXyzHit.getHighlightField("type")).hasSize(1).contains("abc <em>xyz</em>");
|
assertThat(highlightXyzHit.getHighlightField("type")).hasSize(1).contains("abc <em>xyz</em>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnDifferentHighlightsOnAnnotatedStringQueryMethodSpEL() {
|
||||||
|
List<SampleEntity> entities = createSampleEntities("abc xyz", 2);
|
||||||
|
repository.saveAll(entities);
|
||||||
|
|
||||||
|
// when
|
||||||
|
SearchHits<SampleEntity> highlightAbcHits = repository.queryByStringWithSeparateHighlightSpEL("abc", "abc");
|
||||||
|
|
||||||
|
assertThat(highlightAbcHits.getTotalHits()).isEqualTo(2);
|
||||||
|
SearchHit<SampleEntity> highlightAbcHit = highlightAbcHits.getSearchHit(0);
|
||||||
|
assertThat(highlightAbcHit.getHighlightField("type")).hasSize(1).contains("<em>abc</em> xyz");
|
||||||
|
|
||||||
|
// when
|
||||||
|
SearchHits<SampleEntity> highlightXyzHits = repository.queryByStringWithSeparateHighlightSpEL("abc", "xyz");
|
||||||
|
|
||||||
|
assertThat(highlightXyzHits.getTotalHits()).isEqualTo(2);
|
||||||
|
SearchHit<SampleEntity> highlightXyzHit = highlightXyzHits.getSearchHit(0);
|
||||||
|
assertThat(highlightXyzHit.getHighlightField("type")).hasSize(1).contains("abc <em>xyz</em>");
|
||||||
|
}
|
||||||
|
|
||||||
@Test // DATAES-734
|
@Test // DATAES-734
|
||||||
void shouldUseGeoSortParameter() {
|
void shouldUseGeoSortParameter() {
|
||||||
GeoPoint munich = new GeoPoint(48.137154, 11.5761247);
|
GeoPoint munich = new GeoPoint(48.137154, 11.5761247);
|
||||||
@ -1938,6 +1958,28 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
assertThat(foundEntity.getKeyword()).isNull();
|
assertThat(foundEntity.getKeyword()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should use sourceIncludes from parameter SpEL")
|
||||||
|
void shouldUseSourceIncludesFromParameterSpEL() {
|
||||||
|
|
||||||
|
SampleEntity entity = new SampleEntity();
|
||||||
|
entity.setId("42");
|
||||||
|
entity.setMessage("message");
|
||||||
|
entity.setCustomFieldNameMessage("customFieldNameMessage");
|
||||||
|
entity.setType("type");
|
||||||
|
entity.setKeyword("keyword");
|
||||||
|
repository.save(entity);
|
||||||
|
|
||||||
|
var searchHits = repository.queryBy(List.of("message", "customFieldNameMessage"));
|
||||||
|
|
||||||
|
assertThat(searchHits.hasSearchHits()).isTrue();
|
||||||
|
var foundEntity = searchHits.getSearchHit(0).getContent();
|
||||||
|
assertThat(foundEntity.getMessage()).isEqualTo("message");
|
||||||
|
assertThat(foundEntity.getCustomFieldNameMessage()).isEqualTo("customFieldNameMessage");
|
||||||
|
assertThat(foundEntity.getType()).isNull();
|
||||||
|
assertThat(foundEntity.getKeyword()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test // #2146
|
@Test // #2146
|
||||||
@DisplayName("should use sourceExcludes from annotation")
|
@DisplayName("should use sourceExcludes from annotation")
|
||||||
void shouldUseSourceExcludesFromAnnotation() {
|
void shouldUseSourceExcludesFromAnnotation() {
|
||||||
@ -1982,6 +2024,28 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
assertThat(foundEntity.getKeyword()).isNull();
|
assertThat(foundEntity.getKeyword()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should use source excludes from parameter SpEL")
|
||||||
|
void shouldUseSourceExcludesFromParameterSpEL() {
|
||||||
|
|
||||||
|
SampleEntity entity = new SampleEntity();
|
||||||
|
entity.setId("42");
|
||||||
|
entity.setMessage("message");
|
||||||
|
entity.setCustomFieldNameMessage("customFieldNameMessage");
|
||||||
|
entity.setType("type");
|
||||||
|
entity.setKeyword("keyword");
|
||||||
|
repository.save(entity);
|
||||||
|
|
||||||
|
var searchHits = repository.getBy(List.of("type", "keyword"));
|
||||||
|
|
||||||
|
assertThat(searchHits.hasSearchHits()).isTrue();
|
||||||
|
var foundEntity = searchHits.getSearchHit(0).getContent();
|
||||||
|
assertThat(foundEntity.getMessage()).isEqualTo("message");
|
||||||
|
assertThat(foundEntity.getCustomFieldNameMessage()).isEqualTo("customFieldNameMessage");
|
||||||
|
assertThat(foundEntity.getType()).isNull();
|
||||||
|
assertThat(foundEntity.getKeyword()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
private List<SampleEntity> createSampleEntities(String type, int numberOfEntities) {
|
private List<SampleEntity> createSampleEntities(String type, int numberOfEntities) {
|
||||||
|
|
||||||
List<SampleEntity> entities = new ArrayList<>();
|
List<SampleEntity> entities = new ArrayList<>();
|
||||||
@ -2276,6 +2340,37 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
""")))
|
""")))
|
||||||
SearchHits<SampleEntity> queryByStringWithSeparateHighlight(String type, String highlight);
|
SearchHits<SampleEntity> queryByStringWithSeparateHighlight(String type, String highlight);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"type":"#{#type}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
@Highlight(
|
||||||
|
fields = { @HighlightField(name = "type") },
|
||||||
|
parameters = @HighlightParameters(
|
||||||
|
highlightQuery = @Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"type":"#{#highlight}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")))
|
||||||
|
SearchHits<SampleEntity> queryByStringWithSeparateHighlightSpEL(String type, String highlight);
|
||||||
|
|
||||||
List<SearchHit<SampleEntity>> queryByMessage(String message);
|
List<SearchHit<SampleEntity>> queryByMessage(String message);
|
||||||
|
|
||||||
Stream<SearchHit<SampleEntity>> readByMessage(String message);
|
Stream<SearchHit<SampleEntity>> readByMessage(String message);
|
||||||
@ -2307,6 +2402,9 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
@SourceFilters(includes = "?0")
|
@SourceFilters(includes = "?0")
|
||||||
SearchHits<SampleEntity> searchBy(Collection<String> sourceIncludes);
|
SearchHits<SampleEntity> searchBy(Collection<String> sourceIncludes);
|
||||||
|
|
||||||
|
@SourceFilters(includes = "#{#sourceIncludes}")
|
||||||
|
SearchHits<SampleEntity> queryBy(Collection<String> sourceIncludes);
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
{
|
{
|
||||||
"match_all": {}
|
"match_all": {}
|
||||||
@ -2317,6 +2415,9 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
|||||||
|
|
||||||
@SourceFilters(excludes = "?0")
|
@SourceFilters(excludes = "?0")
|
||||||
SearchHits<SampleEntity> findBy(Collection<String> sourceExcludes);
|
SearchHits<SampleEntity> findBy(Collection<String> sourceExcludes);
|
||||||
|
|
||||||
|
@SourceFilters(excludes = "#{#sourceExcludes}")
|
||||||
|
SearchHits<SampleEntity> getBy(Collection<String> sourceExcludes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SampleStreamingCustomMethodRepository extends ElasticsearchRepository<SampleEntity, String> {
|
public interface SampleStreamingCustomMethodRepository extends ElasticsearchRepository<SampleEntity, String> {
|
||||||
|
@ -52,7 +52,6 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
|||||||
import org.springframework.data.repository.Repository;
|
import org.springframework.data.repository.Repository;
|
||||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,8 +62,6 @@ import org.springframework.lang.Nullable;
|
|||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStringQueryUnitTestBase {
|
public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStringQueryUnitTestBase {
|
||||||
|
|
||||||
SpelExpressionParser PARSER = new SpelExpressionParser();
|
|
||||||
|
|
||||||
@Mock ReactiveElasticsearchOperations operations;
|
@Mock ReactiveElasticsearchOperations operations;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@ -377,7 +374,7 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ReactiveElasticsearchStringQuery queryForMethod(ReactiveElasticsearchQueryMethod queryMethod) {
|
private ReactiveElasticsearchStringQuery queryForMethod(ReactiveElasticsearchQueryMethod queryMethod) {
|
||||||
return new ReactiveElasticsearchStringQuery(queryMethod, operations, PARSER,
|
return new ReactiveElasticsearchStringQuery(queryMethod, operations,
|
||||||
QueryMethodEvaluationContextProvider.DEFAULT);
|
QueryMethodEvaluationContextProvider.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ import org.springframework.data.elasticsearch.annotations.Field;
|
|||||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
import org.springframework.data.elasticsearch.annotations.Highlight;
|
import org.springframework.data.elasticsearch.annotations.Highlight;
|
||||||
import org.springframework.data.elasticsearch.annotations.HighlightField;
|
import org.springframework.data.elasticsearch.annotations.HighlightField;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.HighlightParameters;
|
||||||
import org.springframework.data.elasticsearch.annotations.Query;
|
import org.springframework.data.elasticsearch.annotations.Query;
|
||||||
import org.springframework.data.elasticsearch.annotations.SourceFilters;
|
import org.springframework.data.elasticsearch.annotations.SourceFilters;
|
||||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||||
@ -436,6 +437,60 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnDifferentHighlightsOnAnnotatedStringQueryMethod() {
|
||||||
|
|
||||||
|
bulkIndex(new SampleEntity("id-one", "abc xyz"), //
|
||||||
|
new SampleEntity("id-two", "abc xyz"), //
|
||||||
|
new SampleEntity("id-three", "abc xyz")) //
|
||||||
|
.block();
|
||||||
|
|
||||||
|
repository.queryByMessageWithSeparateHighlight("abc", "abc") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectNextMatches(searchHit -> {
|
||||||
|
List<String> hitHighlightField = searchHit.getHighlightField("message");
|
||||||
|
return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("<em>abc</em> xyz");
|
||||||
|
}) //
|
||||||
|
.expectNextCount(2) //
|
||||||
|
.verifyComplete();
|
||||||
|
|
||||||
|
repository.queryByMessageWithSeparateHighlight("abc", "xyz") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectNextMatches(searchHit -> {
|
||||||
|
List<String> hitHighlightField = searchHit.getHighlightField("message");
|
||||||
|
return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("abc <em>xyz</em>");
|
||||||
|
}) //
|
||||||
|
.expectNextCount(2) //
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnDifferentHighlightsOnAnnotatedStringQueryMethodSpEL() {
|
||||||
|
|
||||||
|
bulkIndex(new SampleEntity("id-one", "abc xyz"), //
|
||||||
|
new SampleEntity("id-two", "abc xyz"), //
|
||||||
|
new SampleEntity("id-three", "abc xyz")) //
|
||||||
|
.block();
|
||||||
|
|
||||||
|
repository.queryByMessageWithSeparateHighlightSpEL("abc", "abc") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectNextMatches(searchHit -> {
|
||||||
|
List<String> hitHighlightField = searchHit.getHighlightField("message");
|
||||||
|
return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("<em>abc</em> xyz");
|
||||||
|
}) //
|
||||||
|
.expectNextCount(2) //
|
||||||
|
.verifyComplete();
|
||||||
|
|
||||||
|
repository.queryByMessageWithSeparateHighlightSpEL("abc", "xyz") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectNextMatches(searchHit -> {
|
||||||
|
List<String> hitHighlightField = searchHit.getHighlightField("message");
|
||||||
|
return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("abc <em>xyz</em>");
|
||||||
|
}) //
|
||||||
|
.expectNextCount(2) //
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
@Test // DATAES-519, DATAES-767, DATAES-822
|
@Test // DATAES-519, DATAES-767, DATAES-822
|
||||||
void countShouldErrorWhenIndexDoesNotExist() {
|
void countShouldErrorWhenIndexDoesNotExist() {
|
||||||
|
|
||||||
@ -860,6 +915,29 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should use sourceIncludes from parameter SpEL")
|
||||||
|
void shouldUseSourceIncludesFromParameterSpEL() {
|
||||||
|
|
||||||
|
var entity = new SampleEntity();
|
||||||
|
entity.setId("42");
|
||||||
|
entity.setMessage("message");
|
||||||
|
entity.setCustomFieldNameMessage("customFieldNameMessage");
|
||||||
|
entity.setType("type");
|
||||||
|
entity.setKeyword("keyword");
|
||||||
|
repository.save(entity).block();
|
||||||
|
|
||||||
|
repository.queryBy(List.of("message", "customFieldNameMessage")) //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.consumeNextWith(foundEntity -> { //
|
||||||
|
assertThat(foundEntity.getMessage()).isEqualTo("message"); //
|
||||||
|
assertThat(foundEntity.getCustomFieldNameMessage()).isEqualTo("customFieldNameMessage"); //
|
||||||
|
assertThat(foundEntity.getType()).isNull(); //
|
||||||
|
assertThat(foundEntity.getKeyword()).isNull(); //
|
||||||
|
}) //
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
@Test // #2146
|
@Test // #2146
|
||||||
@DisplayName("should use sourceExcludes from annotation")
|
@DisplayName("should use sourceExcludes from annotation")
|
||||||
void shouldUseSourceExcludesFromAnnotation() {
|
void shouldUseSourceExcludesFromAnnotation() {
|
||||||
@ -906,6 +984,29 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("should use source excludes from parameter SpEL")
|
||||||
|
void shouldUseSourceExcludesFromParameterSpEL() {
|
||||||
|
|
||||||
|
var entity = new SampleEntity();
|
||||||
|
entity.setId("42");
|
||||||
|
entity.setMessage("message");
|
||||||
|
entity.setCustomFieldNameMessage("customFieldNameMessage");
|
||||||
|
entity.setType("type");
|
||||||
|
entity.setKeyword("keyword");
|
||||||
|
repository.save(entity).block();
|
||||||
|
|
||||||
|
repository.getBy(List.of("type", "keyword")) //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.consumeNextWith(foundEntity -> { //
|
||||||
|
assertThat(foundEntity.getMessage()).isEqualTo("message"); //
|
||||||
|
assertThat(foundEntity.getCustomFieldNameMessage()).isEqualTo("customFieldNameMessage"); //
|
||||||
|
assertThat(foundEntity.getType()).isNull(); //
|
||||||
|
assertThat(foundEntity.getKeyword()).isNull(); //
|
||||||
|
}) //
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
@Test // #2496
|
@Test // #2496
|
||||||
@DisplayName("should save data from Flux and return saved data in a flux")
|
@DisplayName("should save data from Flux and return saved data in a flux")
|
||||||
void shouldSaveDataFromFluxAndReturnSavedDataInAFlux() {
|
void shouldSaveDataFromFluxAndReturnSavedDataInAFlux() {
|
||||||
@ -947,6 +1048,68 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
@Highlight(fields = { @HighlightField(name = "message") })
|
@Highlight(fields = { @HighlightField(name = "message") })
|
||||||
Flux<SearchHit<SampleEntity>> queryByMessageWithString(String message);
|
Flux<SearchHit<SampleEntity>> queryByMessageWithString(String message);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"message":"?0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
@Highlight(
|
||||||
|
fields = { @HighlightField(name = "message") },
|
||||||
|
parameters = @HighlightParameters(
|
||||||
|
highlightQuery = @Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"message":"?1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")))
|
||||||
|
Flux<SearchHit<SampleEntity>> queryByMessageWithSeparateHighlight(String message, String highlight);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"message":"#{#message}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
@Highlight(
|
||||||
|
fields = { @HighlightField(name = "message") },
|
||||||
|
parameters = @HighlightParameters(
|
||||||
|
highlightQuery = @Query("""
|
||||||
|
{
|
||||||
|
"bool":{
|
||||||
|
"must":[
|
||||||
|
{
|
||||||
|
"match":{
|
||||||
|
"message":"#{#highlight}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")))
|
||||||
|
Flux<SearchHit<SampleEntity>> queryByMessageWithSeparateHighlightSpEL(String message, String highlight);
|
||||||
|
|
||||||
@Query("{ \"bool\" : { \"must\" : { \"term\" : { \"message\" : \"?0\" } } } }")
|
@Query("{ \"bool\" : { \"must\" : { \"term\" : { \"message\" : \"?0\" } } } }")
|
||||||
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageLike(String message);
|
Flux<SampleEntity> findAllViaAnnotatedQueryByMessageLike(String message);
|
||||||
|
|
||||||
@ -1083,6 +1246,9 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
@SourceFilters(includes = "?0")
|
@SourceFilters(includes = "?0")
|
||||||
Flux<SampleEntity> searchBy(Collection<String> sourceIncludes);
|
Flux<SampleEntity> searchBy(Collection<String> sourceIncludes);
|
||||||
|
|
||||||
|
@SourceFilters(includes = "#{#sourceIncludes}")
|
||||||
|
Flux<SampleEntity> queryBy(Collection<String> sourceIncludes);
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
{
|
{
|
||||||
"match_all": {}
|
"match_all": {}
|
||||||
@ -1093,6 +1259,9 @@ abstract class SimpleReactiveElasticsearchRepositoryIntegrationTests {
|
|||||||
|
|
||||||
@SourceFilters(excludes = "?0")
|
@SourceFilters(excludes = "?0")
|
||||||
Flux<SampleEntity> findBy(Collection<String> sourceExcludes);
|
Flux<SampleEntity> findBy(Collection<String> sourceExcludes);
|
||||||
|
|
||||||
|
@SourceFilters(excludes = "#{#sourceExcludes}")
|
||||||
|
Flux<SampleEntity> getBy(Collection<String> sourceExcludes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
@Document(indexName = "#{@indexNameProvider.indexName()}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user