mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-08 21:22:12 +00:00
DATES-615 - Use annotated field name on repository order by clause.
Original PR: #298
This commit is contained in:
parent
d1aa604fe5
commit
9e93dd08aa
@ -449,7 +449,7 @@ public class ElasticsearchRestTemplate
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor) {
|
public <T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor) {
|
||||||
SearchResponse response = doSearch(prepareSearch(query, Optional.ofNullable(query.getQuery())), query);
|
SearchResponse response = doSearch(prepareSearch(query, Optional.ofNullable(query.getQuery()), null), query);
|
||||||
return resultsExtractor.extract(response);
|
return resultsExtractor.extract(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ public class ElasticsearchRestTemplate
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> List<String> queryForIds(SearchQuery query) {
|
public <T> List<String> queryForIds(SearchQuery query) {
|
||||||
SearchRequest request = prepareSearch(query, Optional.ofNullable(query.getQuery()));
|
SearchRequest request = prepareSearch(query, Optional.ofNullable(query.getQuery()), null);
|
||||||
request.source().query(query.getQuery());
|
request.source().query(query.getQuery());
|
||||||
if (query.getFilter() != null) {
|
if (query.getFilter() != null) {
|
||||||
request.source().postFilter(query.getFilter());
|
request.source().postFilter(query.getFilter());
|
||||||
@ -627,10 +627,10 @@ public class ElasticsearchRestTemplate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <T> SearchRequest prepareCount(Query query, Class<T> clazz) {
|
private <T> SearchRequest prepareCount(Query query, Class<T> clazz) {
|
||||||
String indexName[] = !isEmpty(query.getIndices())
|
String[] indexName = !isEmpty(query.getIndices())
|
||||||
? query.getIndices().toArray(new String[query.getIndices().size()])
|
? query.getIndices().toArray(new String[query.getIndices().size()])
|
||||||
: retrieveIndexNameFromPersistentEntity(clazz);
|
: retrieveIndexNameFromPersistentEntity(clazz);
|
||||||
String types[] = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()])
|
String[] types = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()])
|
||||||
: retrieveTypeFromPersistentEntity(clazz);
|
: retrieveTypeFromPersistentEntity(clazz);
|
||||||
|
|
||||||
Assert.notNull(indexName, "No index defined for Query");
|
Assert.notNull(indexName, "No index defined for Query");
|
||||||
@ -920,10 +920,12 @@ public class ElasticsearchRestTemplate
|
|||||||
|
|
||||||
private <T> SearchRequest prepareScroll(Query query, long scrollTimeInMillis, Class<T> clazz) {
|
private <T> SearchRequest prepareScroll(Query query, long scrollTimeInMillis, Class<T> clazz) {
|
||||||
setPersistentEntityIndexAndType(query, clazz);
|
setPersistentEntityIndexAndType(query, clazz);
|
||||||
return prepareScroll(query, scrollTimeInMillis);
|
ElasticsearchPersistentEntity<?> entity = getPersistentEntity(clazz);
|
||||||
|
return prepareScroll(query, scrollTimeInMillis, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchRequest prepareScroll(Query query, long scrollTimeInMillis) {
|
private SearchRequest prepareScroll(Query query, long scrollTimeInMillis,
|
||||||
|
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||||
SearchRequest request = new SearchRequest(toArray(query.getIndices()));
|
SearchRequest request = new SearchRequest(toArray(query.getIndices()));
|
||||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||||
request.types(toArray(query.getTypes()));
|
request.types(toArray(query.getTypes()));
|
||||||
@ -943,7 +945,7 @@ public class ElasticsearchRestTemplate
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query.getSort() != null) {
|
if (query.getSort() != null) {
|
||||||
prepareSort(query, searchSourceBuilder);
|
prepareSort(query, searchSourceBuilder, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
request.source(searchSourceBuilder);
|
request.source(searchSourceBuilder);
|
||||||
@ -1272,15 +1274,15 @@ public class ElasticsearchRestTemplate
|
|||||||
|
|
||||||
private <T> SearchRequest prepareSearch(Query query, Class<T> clazz) {
|
private <T> SearchRequest prepareSearch(Query query, Class<T> clazz) {
|
||||||
setPersistentEntityIndexAndType(query, clazz);
|
setPersistentEntityIndexAndType(query, clazz);
|
||||||
return prepareSearch(query, Optional.empty());
|
return prepareSearch(query, Optional.empty(), clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> SearchRequest prepareSearch(SearchQuery query, Class<T> clazz) {
|
private <T> SearchRequest prepareSearch(SearchQuery query, Class<T> clazz) {
|
||||||
setPersistentEntityIndexAndType(query, clazz);
|
setPersistentEntityIndexAndType(query, clazz);
|
||||||
return prepareSearch(query, Optional.ofNullable(query.getQuery()));
|
return prepareSearch(query, Optional.ofNullable(query.getQuery()), clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchRequest prepareSearch(Query query, Optional<QueryBuilder> builder) {
|
private SearchRequest prepareSearch(Query query, Optional<QueryBuilder> builder, @Nullable Class<?> clazz) {
|
||||||
Assert.notNull(query.getIndices(), "No index defined for Query");
|
Assert.notNull(query.getIndices(), "No index defined for Query");
|
||||||
Assert.notNull(query.getTypes(), "No type defined for Query");
|
Assert.notNull(query.getTypes(), "No type defined for Query");
|
||||||
|
|
||||||
@ -1315,7 +1317,7 @@ public class ElasticsearchRestTemplate
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query.getSort() != null) {
|
if (query.getSort() != null) {
|
||||||
prepareSort(query, sourceBuilder);
|
prepareSort(query, sourceBuilder, getPersistentEntity(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.getMinScore() > 0) {
|
if (query.getMinScore() > 0) {
|
||||||
@ -1330,9 +1332,14 @@ public class ElasticsearchRestTemplate
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareSort(Query query, SearchSourceBuilder sourceBuilder) {
|
private void prepareSort(Query query, SearchSourceBuilder sourceBuilder,
|
||||||
|
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||||
for (Sort.Order order : query.getSort()) {
|
for (Sort.Order order : query.getSort()) {
|
||||||
FieldSortBuilder sort = SortBuilders.fieldSort(order.getProperty())
|
ElasticsearchPersistentProperty property = entity != null //
|
||||||
|
? entity.getPersistentProperty(order.getProperty()) //
|
||||||
|
: null;
|
||||||
|
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
||||||
|
FieldSortBuilder sort = SortBuilders.fieldSort(fieldName)
|
||||||
.order(order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC);
|
.order(order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC);
|
||||||
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
||||||
sort.missing("_first");
|
sort.missing("_first");
|
||||||
@ -1455,6 +1462,11 @@ public class ElasticsearchRestTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ElasticsearchPersistentEntity<?> getPersistentEntity(@Nullable Class<?> clazz) {
|
||||||
|
return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) {
|
public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) {
|
||||||
Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName()
|
Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName()
|
||||||
|
@ -389,7 +389,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor) {
|
public <T> T query(SearchQuery query, ResultsExtractor<T> resultsExtractor) {
|
||||||
SearchResponse response = doSearch(prepareSearch(query), query);
|
SearchResponse response = doSearch(prepareSearch(query, (ElasticsearchPersistentEntity) null), query);
|
||||||
return resultsExtractor.extract(response);
|
return resultsExtractor.extract(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +410,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> List<String> queryForIds(SearchQuery query) {
|
public <T> List<String> queryForIds(SearchQuery query) {
|
||||||
SearchRequestBuilder request = prepareSearch(query).setQuery(query.getQuery());
|
SearchRequestBuilder request = prepareSearch(query, (ElasticsearchPersistentEntity) null)
|
||||||
|
.setQuery(query.getQuery());
|
||||||
if (query.getFilter() != null) {
|
if (query.getFilter() != null) {
|
||||||
request.setPostFilter(query.getFilter());
|
request.setPostFilter(query.getFilter());
|
||||||
}
|
}
|
||||||
@ -781,10 +782,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
|
|
||||||
private <T> SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis, Class<T> clazz) {
|
private <T> SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis, Class<T> clazz) {
|
||||||
setPersistentEntityIndexAndType(query, clazz);
|
setPersistentEntityIndexAndType(query, clazz);
|
||||||
return prepareScroll(query, scrollTimeInMillis);
|
return prepareScroll(query, scrollTimeInMillis, getPersistentEntity(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis) {
|
private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis,
|
||||||
|
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||||
SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices()))
|
SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices()))
|
||||||
.setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0)
|
.setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0)
|
||||||
.setVersion(true);
|
.setVersion(true);
|
||||||
@ -803,7 +805,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query.getSort() != null) {
|
if (query.getSort() != null) {
|
||||||
prepareSort(query, requestBuilder);
|
prepareSort(query, requestBuilder, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestBuilder;
|
return requestBuilder;
|
||||||
@ -1070,10 +1072,10 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
|
|
||||||
private <T> SearchRequestBuilder prepareSearch(Query query, Class<T> clazz) {
|
private <T> SearchRequestBuilder prepareSearch(Query query, Class<T> clazz) {
|
||||||
setPersistentEntityIndexAndType(query, clazz);
|
setPersistentEntityIndexAndType(query, clazz);
|
||||||
return prepareSearch(query);
|
return prepareSearch(query, getPersistentEntity(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchRequestBuilder prepareSearch(Query query) {
|
private SearchRequestBuilder prepareSearch(Query query, @Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||||
Assert.notNull(query.getIndices(), "No index defined for Query");
|
Assert.notNull(query.getIndices(), "No index defined for Query");
|
||||||
Assert.notNull(query.getTypes(), "No type defined for Query");
|
Assert.notNull(query.getTypes(), "No type defined for Query");
|
||||||
|
|
||||||
@ -1102,7 +1104,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query.getSort() != null) {
|
if (query.getSort() != null) {
|
||||||
prepareSort(query, searchRequestBuilder);
|
prepareSort(query, searchRequestBuilder, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.getMinScore() > 0) {
|
if (query.getMinScore() > 0) {
|
||||||
@ -1116,7 +1118,8 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
return searchRequestBuilder;
|
return searchRequestBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder) {
|
private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder,
|
||||||
|
@Nullable ElasticsearchPersistentEntity<?> entity) {
|
||||||
for (Sort.Order order : query.getSort()) {
|
for (Sort.Order order : query.getSort()) {
|
||||||
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
|
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
|
||||||
|
|
||||||
@ -1127,8 +1130,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
|
|
||||||
searchRequestBuilder.addSort(sort);
|
searchRequestBuilder.addSort(sort);
|
||||||
} else {
|
} else {
|
||||||
|
ElasticsearchPersistentProperty property = entity != null //
|
||||||
|
? entity.getPersistentProperty(order.getProperty()) //
|
||||||
|
: null;
|
||||||
|
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
||||||
FieldSortBuilder sort = SortBuilders //
|
FieldSortBuilder sort = SortBuilders //
|
||||||
.fieldSort(order.getProperty()) //
|
.fieldSort(fieldName) //
|
||||||
.order(sortOrder);
|
.order(sortOrder);
|
||||||
|
|
||||||
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
|
||||||
@ -1203,6 +1210,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
|
|||||||
.get(indexName);
|
.get(indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private ElasticsearchPersistentEntity<?> getPersistentEntity(@Nullable Class<?> clazz) {
|
||||||
|
return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) {
|
public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) {
|
||||||
Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName()
|
Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName()
|
||||||
|
@ -25,6 +25,7 @@ import org.springframework.data.repository.query.ParametersParameterAccessor;
|
|||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
import org.springframework.data.util.CloseableIterator;
|
import org.springframework.data.util.CloseableIterator;
|
||||||
import org.springframework.data.util.StreamUtils;
|
import org.springframework.data.util.StreamUtils;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,6 +36,7 @@ import org.springframework.util.ClassUtils;
|
|||||||
* @author Kevin Leturc
|
* @author Kevin Leturc
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Rasmus Faber-Espensen
|
* @author Rasmus Faber-Espensen
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
|
public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery {
|
||||||
|
|
||||||
@ -54,45 +56,38 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
|
|||||||
|
|
||||||
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
|
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
|
||||||
CriteriaQuery query = createQuery(accessor);
|
CriteriaQuery query = createQuery(accessor);
|
||||||
if (tree.isDelete()) {
|
Assert.notNull(query, "unsupported query");
|
||||||
|
|
||||||
|
if (tree.isDelete()) {
|
||||||
Object result = countOrGetDocumentsForDelete(query, accessor);
|
Object result = countOrGetDocumentsForDelete(query, accessor);
|
||||||
elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType());
|
elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
return result;
|
return result;
|
||||||
} else if (queryMethod.isPageQuery()) {
|
} else if (queryMethod.isPageQuery()) {
|
||||||
|
|
||||||
query.setPageable(accessor.getPageable());
|
query.setPageable(accessor.getPageable());
|
||||||
return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType());
|
return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
} else if (queryMethod.isStreamQuery()) {
|
} else if (queryMethod.isStreamQuery()) {
|
||||||
|
|
||||||
Class<?> entityType = queryMethod.getEntityInformation().getJavaType();
|
Class<?> entityType = queryMethod.getEntityInformation().getJavaType();
|
||||||
if (accessor.getPageable().isUnpaged()) {
|
if (accessor.getPageable().isUnpaged()) {
|
||||||
|
|
||||||
query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE));
|
query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE));
|
||||||
} else {
|
} else {
|
||||||
|
query.setPageable(accessor.getPageable());
|
||||||
|
}
|
||||||
|
return StreamUtils
|
||||||
|
.createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType));
|
||||||
|
} else if (queryMethod.isCollectionQuery()) {
|
||||||
|
|
||||||
|
if (accessor.getPageable().isUnpaged()) {
|
||||||
|
|
||||||
|
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
|
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
|
||||||
|
} else {
|
||||||
query.setPageable(accessor.getPageable());
|
query.setPageable(accessor.getPageable());
|
||||||
}
|
}
|
||||||
|
|
||||||
return StreamUtils
|
return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
.createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType));
|
} else if (tree.isCountProjection()) {
|
||||||
|
return elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
} else if (queryMethod.isCollectionQuery()) {
|
}
|
||||||
|
|
||||||
if (accessor.getPageable().isUnpaged()) {
|
|
||||||
|
|
||||||
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
|
||||||
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
|
|
||||||
} else {
|
|
||||||
|
|
||||||
query.setPageable(accessor.getPageable());
|
|
||||||
}
|
|
||||||
|
|
||||||
return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
|
|
||||||
} else if (tree.isCountProjection()) {
|
|
||||||
|
|
||||||
return elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
|
||||||
}
|
|
||||||
|
|
||||||
return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType());
|
return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
}
|
}
|
||||||
@ -102,6 +97,7 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
|
|||||||
Object result = null;
|
Object result = null;
|
||||||
|
|
||||||
if (queryMethod.isCollectionQuery()) {
|
if (queryMethod.isCollectionQuery()) {
|
||||||
|
|
||||||
if (accessor.getPageable().isUnpaged()) {
|
if (accessor.getPageable().isUnpaged()) {
|
||||||
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
|
||||||
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
|
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
|
||||||
|
@ -34,6 +34,7 @@ import org.springframework.data.repository.query.ParameterAccessor;
|
|||||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||||
import org.springframework.data.repository.query.parser.Part;
|
import org.springframework.data.repository.query.parser.Part;
|
||||||
import org.springframework.data.repository.query.parser.PartTree;
|
import org.springframework.data.repository.query.parser.PartTree;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ElasticsearchQueryCreator
|
* ElasticsearchQueryCreator
|
||||||
@ -42,13 +43,14 @@ import org.springframework.data.repository.query.parser.PartTree;
|
|||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
* @author Franck Marchand
|
* @author Franck Marchand
|
||||||
* @author Artur Konczak
|
* @author Artur Konczak
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuery, CriteriaQuery> {
|
public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuery, CriteriaQuery> {
|
||||||
|
|
||||||
private final MappingContext<?, ElasticsearchPersistentProperty> context;
|
private final MappingContext<?, ElasticsearchPersistentProperty> context;
|
||||||
|
|
||||||
public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
|
public ElasticsearchQueryCreator(PartTree tree, ParameterAccessor parameters,
|
||||||
MappingContext<?, ElasticsearchPersistentProperty> context) {
|
MappingContext<?, ElasticsearchPersistentProperty> context) {
|
||||||
super(tree, parameters);
|
super(tree, parameters);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
@ -83,9 +85,12 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CriteriaQuery complete(CriteriaQuery query, Sort sort) {
|
protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) {
|
||||||
|
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
return null;
|
|
||||||
|
// this is the case in a findAllByOrderByField method, add empty criteria
|
||||||
|
query = new CriteriaQuery(new Criteria());
|
||||||
}
|
}
|
||||||
return query.addSort(sort);
|
return query.addSort(sort);
|
||||||
}
|
}
|
||||||
@ -190,6 +195,6 @@ public class ElasticsearchQueryCreator extends AbstractQueryCreator<CriteriaQuer
|
|||||||
} else if (o.getClass().isArray()) {
|
} else if (o.getClass().isArray()) {
|
||||||
return (Object[]) o;
|
return (Object[]) o;
|
||||||
}
|
}
|
||||||
return new Object[]{o};
|
return new Object[] { o };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
|
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
|
||||||
|
import org.springframework.data.elasticsearch.core.ElasticsearchEntityMapper;
|
||||||
|
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||||
|
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration class for the classic ElasticsearchTemplate. Needs a {@link TestNodeResource} bean that should be set up in
|
||||||
|
* the test as ClassRule and exported as bean.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class ElasticsearchTestConfiguration extends ElasticsearchConfigurationSupport {
|
||||||
|
|
||||||
|
@Autowired private TestNodeResource testNodeResource;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Client elasticsearchClient() {
|
||||||
|
return testNodeResource.client();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
|
||||||
|
public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient, EntityMapper entityMapper) {
|
||||||
|
return new ElasticsearchTemplate(elasticsearchClient, entityMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* need the ElasticsearchMapper, because some tests rely on @Field(name) being handled correctly
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public EntityMapper entityMapper() {
|
||||||
|
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
|
||||||
|
new DefaultConversionService());
|
||||||
|
entityMapper.setConversions(elasticsearchCustomConversions());
|
||||||
|
|
||||||
|
return entityMapper;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.RestHighLevelClient;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
|
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
|
||||||
|
import org.springframework.data.elasticsearch.core.ElasticsearchEntityMapper;
|
||||||
|
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RestElasticsearchTestConfiguration extends AbstractElasticsearchConfiguration {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Bean
|
||||||
|
public RestHighLevelClient elasticsearchClient() {
|
||||||
|
return TestUtils.restHighLevelClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* need the ElasticsearchMapper, because some tests rely on @Field(name) being handled correctly
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public EntityMapper entityMapper() {
|
||||||
|
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
|
||||||
|
new DefaultConversionService());
|
||||||
|
entityMapper.setConversions(elasticsearchCustomConversions());
|
||||||
|
|
||||||
|
return entityMapper;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.node.Node;
|
||||||
|
import org.junit.rules.ExternalResource;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JUnit4 Rule that sets up and tears down a local Elasticsearch node.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
public class TestNodeResource extends ExternalResource {
|
||||||
|
|
||||||
|
private static Node node;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void before() throws Throwable {
|
||||||
|
node = Utils.getNode();
|
||||||
|
node.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void after() {
|
||||||
|
if (node != null) {
|
||||||
|
try {
|
||||||
|
node.close();
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client client() {
|
||||||
|
Assert.notNull(node, "node is not initialized");
|
||||||
|
return node.client();
|
||||||
|
}
|
||||||
|
}
|
@ -15,33 +15,42 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.elasticsearch;
|
package org.springframework.data.elasticsearch;
|
||||||
|
|
||||||
import static java.util.Arrays.*;
|
import java.util.Collections;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.node.Node;
|
||||||
import org.elasticsearch.node.NodeValidationException;
|
import org.elasticsearch.node.NodeValidationException;
|
||||||
import org.elasticsearch.transport.Netty4Plugin;
|
import org.elasticsearch.transport.Netty4Plugin;
|
||||||
|
|
||||||
import org.springframework.data.elasticsearch.client.NodeClientFactoryBean;
|
import org.springframework.data.elasticsearch.client.NodeClientFactoryBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
* @author Artur Konczak
|
* @author Artur Konczak
|
||||||
* @author Ilkang Na
|
* @author Ilkang Na
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
public static Client getNodeClient() throws NodeValidationException {
|
public static Node getNode() {
|
||||||
|
|
||||||
String pathHome = "src/test/resources/test-home-dir";
|
String pathHome = "src/test/resources/test-home-dir";
|
||||||
String pathData = "target/elasticsearchTestData";
|
String pathData = "target/elasticsearchTestData";
|
||||||
String clusterName = UUID.randomUUID().toString();
|
String clusterName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
return new NodeClientFactoryBean.TestNode(Settings.builder().put("transport.type", "netty4")
|
return new NodeClientFactoryBean.TestNode( //
|
||||||
.put("http.type", "netty4").put("path.home", pathHome).put("path.data", pathData)
|
Settings.builder() //
|
||||||
.put("cluster.name", clusterName).put("node.max_local_storage_nodes", 100).build(), asList(Netty4Plugin.class))
|
.put("transport.type", "netty4") //
|
||||||
.start().client();
|
.put("http.type", "netty4") //
|
||||||
|
.put("path.home", pathHome) //
|
||||||
|
.put("path.data", pathData) //
|
||||||
|
.put("cluster.name", clusterName) //
|
||||||
|
.put("node.max_local_storage_nodes", 100)//
|
||||||
|
.build(), //
|
||||||
|
Collections.singletonList(Netty4Plugin.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Client getNodeClient() throws NodeValidationException {
|
||||||
|
return getNode().start().client();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.repository.query.keywords;
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.elasticsearch.ElasticsearchTestConfiguration;
|
||||||
|
import org.springframework.data.elasticsearch.TestNodeResource;
|
||||||
|
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link QueryKeywordsTests} using a Repository backed by an ElasticsearchTemplate.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
@ContextConfiguration(classes = { QueryKeywordsRepositoryTests.class, ElasticsearchTestConfiguration.class })
|
||||||
|
@Configuration
|
||||||
|
@EnableElasticsearchRepositories(considerNestedRepositories = true)
|
||||||
|
public class QueryKeywordsRepositoryTests extends QueryKeywordsTests {
|
||||||
|
|
||||||
|
@ClassRule public static TestNodeResource testNodeResource = new TestNodeResource();
|
||||||
|
|
||||||
|
// needed by the ElasticsearchTestConfiguration.
|
||||||
|
@Bean
|
||||||
|
public TestNodeResource nodeResource() {
|
||||||
|
return testNodeResource;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.repository.query.keywords;
|
||||||
|
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.elasticsearch.RestElasticsearchTestConfiguration;
|
||||||
|
import org.springframework.data.elasticsearch.TestNodeResource;
|
||||||
|
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link QueryKeywordsTests} using a Repository backed by an ElasticsearchRestTemplate.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
@ContextConfiguration(classes = { QueryKeywordsRestRepositoryTests.class, RestElasticsearchTestConfiguration.class })
|
||||||
|
@Configuration
|
||||||
|
@EnableElasticsearchRepositories(considerNestedRepositories = true)
|
||||||
|
public class QueryKeywordsRestRepositoryTests extends QueryKeywordsTests {
|
||||||
|
|
||||||
|
@ClassRule public static TestNodeResource testNodeResource = new TestNodeResource();
|
||||||
|
}
|
@ -26,6 +26,7 @@ import lombok.Setter;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -35,36 +36,43 @@ import org.springframework.data.annotation.Id;
|
|||||||
import org.springframework.data.elasticsearch.annotations.Document;
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
import org.springframework.data.elasticsearch.annotations.Field;
|
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.core.ElasticsearchTemplate;
|
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||||
|
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||||
import org.springframework.data.elasticsearch.utils.IndexInitializer;
|
import org.springframework.data.elasticsearch.utils.IndexInitializer;
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* base class for query keyword tests. Implemented by subclasses using ElasticsearchClient and ElasticsearchRestClient
|
||||||
|
* based repositories.
|
||||||
|
*
|
||||||
* @author Artur Konczak
|
* @author Artur Konczak
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration("classpath:/repository-query-keywords.xml")
|
abstract class QueryKeywordsTests {
|
||||||
public class QueryKeywordsTests {
|
|
||||||
|
|
||||||
@Autowired private ProductRepository repository;
|
@Autowired private ProductRepository repository;
|
||||||
|
|
||||||
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
|
@Autowired private ElasticsearchOperations elasticsearchTemplate;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() {
|
public void before() {
|
||||||
|
|
||||||
IndexInitializer.init(elasticsearchTemplate, Product.class);
|
IndexInitializer.init(elasticsearchTemplate, Product.class);
|
||||||
|
|
||||||
repository.saveAll(
|
Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false)
|
||||||
Arrays.asList(Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false).build(),
|
.sortName("sort5").build();
|
||||||
Product.builder().id("2").name("Sugar").text("Cane sugar").price(1.2f).available(true).build(),
|
Product product2 = Product.builder().id("2").name("Sugar").text("Cane sugar").price(1.2f).available(true)
|
||||||
Product.builder().id("3").name("Sugar").text("Beet sugar").price(1.1f).available(true).build(),
|
.sortName("sort4").build();
|
||||||
Product.builder().id("4").name("Salt").text("Rock salt").price(1.9f).available(true).build(),
|
Product product3 = Product.builder().id("3").name("Sugar").text("Beet sugar").price(1.1f).available(true)
|
||||||
Product.builder().id("5").name("Salt").text("Sea salt").price(2.1f).available(false).build()));
|
.sortName("sort3").build();
|
||||||
|
Product product4 = Product.builder().id("4").name("Salt").text("Rock salt").price(1.9f).available(true)
|
||||||
|
.sortName("sort2").build();
|
||||||
|
Product product5 = Product.builder().id("5").name("Salt").text("Sea salt").price(2.1f).available(false)
|
||||||
|
.sortName("sort1").build();
|
||||||
|
|
||||||
|
repository.saveAll(Arrays.asList(product1, product2, product3, product4, product5));
|
||||||
|
|
||||||
elasticsearchTemplate.refresh(Product.class);
|
elasticsearchTemplate.refresh(Product.class);
|
||||||
}
|
}
|
||||||
@ -155,6 +163,40 @@ public class QueryKeywordsTests {
|
|||||||
assertThat(repository.findByPriceGreaterThanEqual(1.9f)).hasSize(2);
|
assertThat(repository.findByPriceGreaterThanEqual(1.9f)).hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-615
|
||||||
|
public void shouldSupportSortOnStandardFieldWithCriteria() {
|
||||||
|
List<String> sortedIds = repository.findAllByNameOrderByText("Salt").stream() //
|
||||||
|
.map(it -> it.id).collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertThat(sortedIds).containsExactly("4", "5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-615
|
||||||
|
public void shouldSupportSortOnFieldWithCustomFieldNameWithCriteria() {
|
||||||
|
|
||||||
|
List<String> sortedIds = repository.findAllByNameOrderBySortName("Sugar").stream() //
|
||||||
|
.map(it -> it.id).collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertThat(sortedIds).containsExactly("3", "2", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-615
|
||||||
|
public void shouldSupportSortOnStandardFieldWithoutCriteria() {
|
||||||
|
List<String> sortedIds = repository.findAllByOrderByText().stream() //
|
||||||
|
.map(it -> it.text).collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertThat(sortedIds).containsExactly("Beet sugar", "Cane sugar", "Cane sugar", "Rock salt", "Sea salt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-615
|
||||||
|
public void shouldSupportSortOnFieldWithCustomFieldNameWithoutCriteria() {
|
||||||
|
|
||||||
|
List<String> sortedIds = repository.findAllByOrderBySortName().stream() //
|
||||||
|
.map(it -> it.id).collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertThat(sortedIds).containsExactly("5", "4", "3", "2", "1");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
* @author Artur Konczak
|
* @author Artur Konczak
|
||||||
@ -176,7 +218,7 @@ public class QueryKeywordsTests {
|
|||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
private String text;
|
@Field(type = FieldType.Keyword) private String text;
|
||||||
|
|
||||||
private List<String> categories;
|
private List<String> categories;
|
||||||
|
|
||||||
@ -191,12 +233,14 @@ public class QueryKeywordsTests {
|
|||||||
private String location;
|
private String location;
|
||||||
|
|
||||||
private Date lastModified;
|
private Date lastModified;
|
||||||
|
|
||||||
|
@Field(name = "sort-name", type = FieldType.Keyword) private String sortName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by akonczak on 04/09/15.
|
* Created by akonczak on 04/09/15.
|
||||||
*/
|
*/
|
||||||
interface ProductRepository extends PagingAndSortingRepository<Product, String> {
|
interface ProductRepository extends ElasticsearchRepository<Product, String> {
|
||||||
|
|
||||||
List<Product> findByNameAndText(String name, String text);
|
List<Product> findByNameAndText(String name, String text);
|
||||||
|
|
||||||
@ -227,6 +271,14 @@ public class QueryKeywordsTests {
|
|||||||
List<Product> findByPriceGreaterThanEqual(float v);
|
List<Product> findByPriceGreaterThanEqual(float v);
|
||||||
|
|
||||||
List<Product> findByIdNotIn(List<String> strings);
|
List<Product> findByIdNotIn(List<String> strings);
|
||||||
|
|
||||||
|
List<Product> findAllByNameOrderByText(String name);
|
||||||
|
|
||||||
|
List<Product> findAllByNameOrderBySortName(String name);
|
||||||
|
|
||||||
|
List<Product> findAllByOrderByText();
|
||||||
|
|
||||||
|
List<Product> findAllByOrderBySortName();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/data/elasticsearch https://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd
|
|
||||||
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
|
||||||
|
|
||||||
<import resource="infrastructure.xml"/>
|
|
||||||
|
|
||||||
<bean name="elasticsearchTemplate"
|
|
||||||
class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
|
|
||||||
<constructor-arg name="client" ref="client"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<elasticsearch:repositories
|
|
||||||
base-package="org.springframework.data.elasticsearch.repository.query.keywords"
|
|
||||||
consider-nested-repositories="true"/>
|
|
||||||
|
|
||||||
</beans>
|
|
Loading…
x
Reference in New Issue
Block a user