DATAES-631 - Consolidate query objects.

Original PR: #340
This commit is contained in:
Peter-Josef Meisch 2019-11-28 23:41:13 +01:00 committed by GitHub
parent 79d75f814c
commit 2cd18178e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 2156 additions and 5333 deletions

View File

@ -1,13 +1,43 @@
package org.springframework.data.elasticsearch.core;
import static org.springframework.util.StringUtils.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
import org.springframework.data.elasticsearch.core.index.MappingBuilder;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@ -16,11 +46,22 @@ import org.springframework.util.StringUtils;
* @author Sascha Woo
* @author Peter-Josef Meisch
*/
public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations {
public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
protected ElasticsearchConverter elasticsearchConverter;
protected RequestFactory requestFactory;
public RequestFactory getRequestFactory() {
return requestFactory;
}
protected void initialize(ElasticsearchConverter elasticsearchConverter) {
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null.");
this.elasticsearchConverter = elasticsearchConverter;
this.requestFactory = new RequestFactory(elasticsearchConverter);
}
protected ElasticsearchConverter createElasticsearchConverter() {
MappingElasticsearchConverter mappingElasticsearchConverter = new MappingElasticsearchConverter(
@ -29,6 +70,13 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
return mappingElasticsearchConverter;
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
if (elasticsearchConverter instanceof ApplicationContextAware) {
((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context);
}
}
protected String buildMapping(Class<?> clazz) {
// load mapping specified in Mapping annotation if present
@ -53,8 +101,208 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
}
}
@Override
public boolean createIndex(String indexName) {
return createIndexIfNotCreated(indexName);
}
private <T> boolean createIndexIfNotCreated(String indexName) {
return indexExists(indexName) || createIndex(indexName, null);
}
@Override
public <T> boolean createIndex(Class<T> clazz) {
return createIndexIfNotCreated(clazz);
}
private <T> boolean createIndexIfNotCreated(Class<T> clazz) {
return indexExists(getPersistentEntityFor(clazz).getIndexName()) || createIndexWithSettings(clazz);
}
private <T> boolean createIndexWithSettings(Class<T> clazz) {
if (clazz.isAnnotationPresent(Setting.class)) {
String settingPath = clazz.getAnnotation(Setting.class).settingPath();
if (hasText(settingPath)) {
String settings = ResourceUtil.readFileFromClasspath(settingPath);
if (hasText(settings)) {
return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings);
}
} else {
LOGGER.info("settingPath in @Setting has to be defined. Using default instead.");
}
}
return createIndex(getPersistentEntityFor(clazz).getIndexName(), getDefaultSettings(getPersistentEntityFor(clazz)));
}
@Override
public <T> boolean createIndex(Class<T> clazz, Object settings) {
return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings);
}
@Override
public void delete(Query query, Class<?> clazz, IndexCoordinates index) {
Assert.notNull(query, "Query must not be null.");
SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index);
DeleteQuery deleteQuery = new DeleteQuery();
deleteQuery.setQuery(searchRequest.source().query());
delete(deleteQuery, index);
}
@Override
public <T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz, IndexCoordinates index) {
Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery");
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index);
return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index);
}
protected static String[] toArray(List<String> values) {
String[] valuesAsArray = new String[values.size()];
return values.toArray(valuesAsArray);
}
@Override
public ElasticsearchConverter getElasticsearchConverter() {
return elasticsearchConverter;
}
@Override
public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) {
Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName()
+ " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")");
return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz);
}
private <T> Map getDefaultSettings(ElasticsearchPersistentEntity<T> persistentEntity) {
if (persistentEntity.isUseServerConfiguration())
return new HashMap();
return new MapBuilder<String, String>().put("index.number_of_shards", String.valueOf(persistentEntity.getShards()))
.put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas()))
.put("index.refresh_interval", persistentEntity.getRefreshInterval())
.put("index.store.type", persistentEntity.getIndexStoreType()).map();
}
protected void checkForBulkOperationFailure(BulkResponse bulkResponse) {
if (bulkResponse.hasFailures()) {
Map<String, String> failedDocuments = new HashMap<>();
for (BulkItemResponse item : bulkResponse.getItems()) {
if (item.isFailed())
failedDocuments.put(item.getId(), item.getFailureMessage());
}
throw new ElasticsearchException(
"Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages ["
+ failedDocuments + "]",
failedDocuments);
}
}
/**
* @param query
* @param clazz
* @deprecated index names and types should not be set in query
*/
@Deprecated
protected void setPersistentEntityIndexAndType(Query query, Class clazz) {
if (query.getIndices().isEmpty()) {
String[] indices = retrieveIndexNameFromPersistentEntity(clazz);
if (indices != null) {
query.addIndices(indices);
}
}
if (query.getTypes().isEmpty()) {
String[] types = retrieveTypeFromPersistentEntity(clazz);
if (types != null) {
query.addTypes(types);
}
}
}
private String[] retrieveIndexNameFromPersistentEntity(Class clazz) {
if (clazz != null) {
return new String[] { getPersistentEntityFor(clazz).getIndexName() };
}
return null;
}
private String[] retrieveTypeFromPersistentEntity(Class clazz) {
if (clazz != null) {
return new String[] { getPersistentEntityFor(clazz).getIndexType() };
}
return null;
}
@Override
public <T> List<Page<T>> queryForPage(List<? extends Query> queries, Class<T> clazz, IndexCoordinates index) {
MultiSearchRequest request = new MultiSearchRequest();
for (Query query : queries) {
request.add(requestFactory.searchRequest(query, clazz, index));
}
return doMultiSearch(queries, clazz, request);
}
@Override
public List<Page<?>> queryForPage(List<? extends Query> queries, List<Class<?>> classes, IndexCoordinates index) {
MultiSearchRequest request = new MultiSearchRequest();
Iterator<Class<?>> it = classes.iterator();
for (Query query : queries) {
request.add(requestFactory.searchRequest(query, it.next(), index));
}
return doMultiSearch(queries, classes, request);
}
private <T> List<Page<T>> doMultiSearch(List<? extends Query> queries, Class<T> clazz, MultiSearchRequest request) {
MultiSearchResponse.Item[] items = getMultiSearchResult(request);
List<Page<T>> res = new ArrayList<>(queries.size());
int c = 0;
for (Query query : queries) {
res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz,
query.getPageable()));
}
return res;
}
private List<Page<?>> doMultiSearch(List<? extends Query> queries, List<Class<?>> classes,
MultiSearchRequest request) {
MultiSearchResponse.Item[] items = getMultiSearchResult(request);
List<Page<?>> res = new ArrayList<>(queries.size());
int c = 0;
Iterator<Class<?>> it = classes.iterator();
for (Query query : queries) {
res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(),
query.getPageable()));
}
return res;
}
@Override
public <T> boolean putMapping(Class<T> clazz) {
return putMapping(clazz, buildMapping(clazz));
}
@Override
public <T> boolean putMapping(Class<T> clazz, Object mapping) {
return putMapping(getIndexCoordinatesFor(clazz), mapping);
}
@Override
public <T> boolean putMapping(IndexCoordinates index, Class<T> clazz) {
return putMapping(index, buildMapping(clazz));
}
abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request);
protected void setPersistentEntityId(Object entity, String id) {
ElasticsearchPersistentEntity<?> persistentEntity = getPersistentEntityFor(entity.getClass());
ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty();
// Only deal with text because ES generated Ids are strings !
if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) {
persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id);
}
}
}

View File

@ -22,9 +22,17 @@ import java.util.stream.Collectors;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.core.query.AliasQuery;
import org.springframework.data.elasticsearch.core.query.BulkOptions;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.util.CloseableIterator;
import org.springframework.lang.Nullable;
@ -44,28 +52,22 @@ public interface ElasticsearchOperations {
* adding new alias
*
* @param query
* @param index
* @return
*/
boolean addAlias(AliasQuery query);
boolean addAlias(AliasQuery query, IndexCoordinates index);
/**
* removing previously created alias
*
* @param query
* @param index
* @return
*/
boolean removeAlias(AliasQuery query);
boolean removeAlias(AliasQuery query, IndexCoordinates index);
/**
* Create an index for a class
*
* @param clazz
* @param <T>
*/
<T> boolean createIndex(Class<T> clazz);
/**
* Create an index for given indexName
* Create an index for given indexName if it does not already exist
*
* @param indexName
*/
@ -79,6 +81,14 @@ public interface ElasticsearchOperations {
*/
boolean createIndex(String indexName, Object settings);
/**
* Create an index for a class if it does not already exist
*
* @param clazz
* @param <T>
*/
<T> boolean createIndex(Class<T> clazz);
/**
* Create an index for given class and Settings
*
@ -96,23 +106,21 @@ public interface ElasticsearchOperations {
<T> boolean putMapping(Class<T> clazz);
/**
* Create mapping for the given class and put the mapping to the given indexName and type.
* Create mapping for the given class and put the mapping to the given index
*
* @param indexName
* @param type
* @param index
* @param clazz
* @since 3.2
*/
<T> boolean putMapping(String indexName, String type, Class<T> clazz);
<T> boolean putMapping(IndexCoordinates index, Class<T> clazz);
/**
* Create mapping for a given indexName and type
*
* @param indexName
* @param type
* Create mapping for a given index
* @param index
* @param mappings
* @param index
*/
boolean putMapping(String indexName, String type, Object mappings);
boolean putMapping(IndexCoordinates index, Object mappings);
/**
* Create mapping for a class
@ -126,17 +134,17 @@ public interface ElasticsearchOperations {
* Get mapping for a class
*
* @param clazz
* @param <T>
*/
<T> Map<String, Object> getMapping(Class<T> clazz);
default Map<String, Object> getMapping(Class<?> clazz) {
return getMapping(getIndexCoordinatesFor(clazz));
}
/**
* Get mapping for a given indexName and type
* Get mapping for a given index coordinates
*
* @param indexName
* @param type
* @param index
*/
Map<String, Object> getMapping(String indexName, String type);
Map<String, Object> getMapping(IndexCoordinates index);
/**
* Get settings for a given indexName
@ -160,34 +168,30 @@ public interface ElasticsearchOperations {
*/
List<AliasMetaData> queryForAlias(String indexName);
<T> T query(NativeSearchQuery query, ResultsExtractor<T> resultsExtractor);
<T> T query(Query query, ResultsExtractor<T> resultsExtractor, Class<T> clazz, IndexCoordinates index);
/**
* Retrieves an object from an index
*
* @param query the query defining the id of the object to get
* @param clazz the type of the object to be returned
* @param index the index from which the object is read.
* @return the found object
*/
<T> T get(GetQuery query, Class<T> clazz, IndexCoordinates index);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @param index
* @return the first matching object
*/
<T> T queryForObject(GetQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @return the first matching object
*/
<T> T queryForObject(CriteriaQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return the first returned object
*
* @param query
* @param clazz
* @return the first matching object
*/
<T> T queryForObject(StringQuery query, Class<T> clazz);
default <T> T queryForObject(Query query, Class<T> clazz, IndexCoordinates index) {
List<T> content = queryForPage(query, clazz, index).getContent();
return content.isEmpty() ? null : content.get(0);
}
/**
* Execute the query against elasticsearch and return result as {@link Page}
@ -196,46 +200,30 @@ public interface ElasticsearchOperations {
* @param clazz
* @return
*/
<T> Page<T> queryForPage(NativeSearchQuery query, Class<T> clazz);
<T> AggregatedPage<T> queryForPage(Query query, Class<T> clazz, IndexCoordinates index);
/**
* Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page}
*
* @param queries
* @param clazz
* @param index
* @return
*/
<T> List<Page<T>> queryForPage(List<NativeSearchQuery> queries, Class<T> clazz);
<T> List<Page<T>> queryForPage(List<? extends Query> queries, Class<T> clazz, IndexCoordinates index);
/**
* Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page}
*
* @param queries
* @param classes
* @param index
* @return
*/
List<Page<?>> queryForPage(List<NativeSearchQuery> queries, List<Class<?>> classes);
List<Page<?>> queryForPage(List<? extends Query> queries, List<Class<?>> classes, IndexCoordinates index);
/**
* Execute the query against elasticsearch and return result as {@link Page}
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(CriteriaQuery query, Class<T> clazz);
/**
* Execute the query against elasticsearch and return result as {@link Page}
*
* @param query
* @param clazz
* @return
*/
<T> Page<T> queryForPage(StringQuery query, Class<T> clazz);
/**
* Executes the given {@link CriteriaQuery} against elasticsearch and return result as {@link CloseableIterator}.
* Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}.
* <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of
* error.
@ -243,65 +231,34 @@ public interface ElasticsearchOperations {
* @param <T> element return type
* @param query
* @param clazz
* @param index
* @return
* @since 1.3
*/
<T> CloseableIterator<T> stream(CriteriaQuery query, Class<T> clazz);
/**
* Executes the given {@link NativeSearchQuery} against elasticsearch and return result as {@link CloseableIterator}.
* <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of
* error.
*
* @param <T> element return type
* @param query
* @param clazz
* @return
* @since 1.3
*/
<T> CloseableIterator<T> stream(NativeSearchQuery query, Class<T> clazz);
<T> CloseableIterator<T> stream(Query query, Class<T> clazz, IndexCoordinates index);
/**
* Execute the criteria query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param index
* @param <T>
* @return
*/
<T> List<T> queryForList(CriteriaQuery query, Class<T> clazz);
/**
* Execute the string query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> List<T> queryForList(StringQuery query, Class<T> clazz);
/**
* Execute the search query against elasticsearch and return result as {@link List}
*
* @param query
* @param clazz
* @param <T>
* @return
*/
<T> List<T> queryForList(NativeSearchQuery query, Class<T> clazz);
<T> List<T> queryForList(Query query, Class<T> clazz, IndexCoordinates index);
/**
* Execute the multi search query against elasticsearch and return result as {@link List}
*
* @param <T>
* @param queries
* @param clazz
* @param <T>
* @param index
* @return
*/
default <T> List<List<T>> queryForList(List<NativeSearchQuery> queries, Class<T> clazz) {
return queryForPage(queries, clazz).stream().map(Page::getContent).collect(Collectors.toList());
default <T> List<List<T>> queryForList(List<Query> queries, Class<T> clazz, IndexCoordinates index) {
return queryForPage(queries, clazz, index).stream().map(Page::getContent).collect(Collectors.toList());
}
/**
@ -309,62 +266,53 @@ public interface ElasticsearchOperations {
*
* @param queries
* @param classes
* @param index
* @return
*/
default List<List<?>> queryForList(List<NativeSearchQuery> queries, List<Class<?>> classes) {
return queryForPage(queries, classes).stream().map(Page::getContent).collect(Collectors.toList());
default List<List<?>> queryForList(List<Query> queries, List<Class<?>> classes, IndexCoordinates index) {
return queryForPage(queries, classes, index).stream().map(Page::getContent).collect(Collectors.toList());
}
/**
* Execute the query against elasticsearch and return ids
*
* @param query
* @return
*/
<T> List<String> queryForIds(NativeSearchQuery query);
/**
* return number of elements found by given query
*
* @param query
* @param clazz
* @param index
* @return
*/
<T> long count(CriteriaQuery query, Class<T> clazz);
List<String> queryForIds(Query query, Class<?> clazz, IndexCoordinates index);
/**
* return number of elements found by given query
*
* @param query
* @return
* @param query the query to execute
* @param index the index to run the query against
* @return count
*/
<T> long count(CriteriaQuery query);
default long count(Query query, IndexCoordinates index) {
return count(query, null, index);
}
/**
* return number of elements found by given query
*
* @param query
* @param clazz
* @return
* @param query the query to execute
* @param clazz the entity clazz used for property mapping
* @param index the index to run the query against
* @return count
*/
<T> long count(NativeSearchQuery query, Class<T> clazz);
/**
* return number of elements found by given query
*
* @param query
* @return
*/
<T> long count(NativeSearchQuery query);
long count(Query query, @Nullable Class<?> clazz, IndexCoordinates index);
/**
* Execute a multiGet against elasticsearch for the given ids
*
* @param searchQuery
* @param query
* @param clazz
* @param index
* @return
*/
<T> List<T> multiGet(NativeSearchQuery searchQuery, Class<T> clazz);
<T> List<T> multiGet(Query query, Class<T> clazz, IndexCoordinates index);
/**
* Index an object. Will do save or update
@ -372,7 +320,7 @@ public interface ElasticsearchOperations {
* @param query
* @return returns the document id
*/
String index(IndexQuery query);
String index(IndexQuery query, IndexCoordinates index);
/**
* Partial update of the document
@ -380,15 +328,15 @@ public interface ElasticsearchOperations {
* @param updateQuery
* @return
*/
UpdateResponse update(UpdateQuery updateQuery);
UpdateResponse update(UpdateQuery updateQuery, IndexCoordinates index);
/**
* Bulk index all objects. Will do save or update.
*
* @param queries the queries to execute in bulk
*/
default void bulkIndex(List<IndexQuery> queries) {
bulkIndex(queries, BulkOptions.defaultOptions());
default void bulkIndex(List<IndexQuery> queries, IndexCoordinates index) {
bulkIndex(queries, BulkOptions.defaultOptions(), index);
}
/**
@ -398,15 +346,15 @@ public interface ElasticsearchOperations {
* @param bulkOptions options to be added to the bulk request
* @since 3.2
*/
void bulkIndex(List<IndexQuery> queries, BulkOptions bulkOptions);
void bulkIndex(List<IndexQuery> queries, BulkOptions bulkOptions, IndexCoordinates index);
/**
* Bulk update all objects. Will do update
*
* @param queries the queries to execute in bulk
*/
default void bulkUpdate(List<UpdateQuery> queries) {
bulkUpdate(queries, BulkOptions.defaultOptions());
default void bulkUpdate(List<UpdateQuery> queries, IndexCoordinates index) {
bulkUpdate(queries, BulkOptions.defaultOptions(), index);
}
/**
@ -416,58 +364,43 @@ public interface ElasticsearchOperations {
* @param bulkOptions options to be added to the bulk request
* @since 3.2
*/
void bulkUpdate(List<UpdateQuery> queries, BulkOptions bulkOptions);
void bulkUpdate(List<UpdateQuery> queries, BulkOptions bulkOptions, IndexCoordinates index);
/**
* Delete the one object with provided id
* Delete the one object with provided id.
*
* @param indexName
* @param type
* @param id
* @param id the document ot delete
* @param index the index from which to delete
* @return documentId of the document deleted
*/
String delete(String indexName, String type, String id);
String delete(String id, IndexCoordinates index);
/**
* Delete all records matching the criteria
*
* @param clazz
* @param criteriaQuery
*/
<T> void delete(CriteriaQuery criteriaQuery, Class<T> clazz);
/**
* Delete the one object with provided id
*
* @param clazz
* @param id
* @return documentId of the document deleted
*/
<T> String delete(Class<T> clazz, String id);
/**
* Delete all records matching the query
*
* @param clazz
*
* @param query
* @param clazz
* @param index
*/
<T> void delete(DeleteQuery query, Class<T> clazz);
void delete(Query query, Class<?> clazz, IndexCoordinates index);
/**
* Delete all records matching the query
*
* @param query
* @param index the index where to delete the records
*/
void delete(DeleteQuery query);
void delete(DeleteQuery query, IndexCoordinates index);
/**
* Deletes an index for given entity
*
* @param clazz
* @param <T>
* @return
*/
<T> boolean deleteIndex(Class<T> clazz);
default boolean deleteIndex(Class<?> clazz) {
return deleteIndex(getPersistentEntityFor(clazz).getIndexName());
}
/**
* Deletes an index for given indexName
@ -481,10 +414,11 @@ public interface ElasticsearchOperations {
* check if index is exists
*
* @param clazz
* @param <T>
* @return
*/
<T> boolean indexExists(Class<T> clazz);
default boolean indexExists(Class<?> clazz) {
return indexExists(getIndexCoordinatesFor(clazz).getIndexName());
}
/**
* check if index is exists for given IndexName
@ -495,49 +429,32 @@ public interface ElasticsearchOperations {
boolean indexExists(String indexName);
/**
* check if type is exists in an index
* refresh the index(es)
*
* @param index
* @param type
* @return
*/
boolean typeExists(String index, String type);
/**
* refresh the index
*
* @param indexName
*/
void refresh(String indexName);
void refresh(IndexCoordinates index);
/**
* refresh the index
*
* @param clazz
*/
<T> void refresh(Class<T> clazz);
default <T> void refresh(Class<T> clazz) {
refresh(getIndexCoordinatesFor(clazz));
}
/**
* Returns scrolled page for given query
*
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param query The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param clazz The class of entity to retrieve.
* @param index
* @return The scan id for input query.
*/
<T> ScrolledPage<T> startScroll(long scrollTimeInMillis, NativeSearchQuery query, Class<T> clazz);
/**
* Returns scrolled page for given query
*
* @param criteriaQuery The search query.
* @param scrollTimeInMillis The time in millisecond for scroll feature
* {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}.
* @param clazz The class of entity to retrieve.
* @return The scan id for input query.
*/
<T> ScrolledPage<T> startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class<T> clazz);
<T> ScrolledPage<T> startScroll(long scrollTimeInMillis, Query query, Class<T> clazz, IndexCoordinates index);
<T> ScrolledPage<T> continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz);
@ -546,17 +463,18 @@ public interface ElasticsearchOperations {
*
* @param scrollId
*/
<T> void clearScroll(String scrollId);
void clearScroll(String scrollId);
/**
* more like this query to search for documents that are "like" a specific document.
*
* @param query
* @param clazz
* @param index
* @param <T>
* @return
*/
<T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz);
<T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz, IndexCoordinates index);
ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz);
@ -564,4 +482,20 @@ public interface ElasticsearchOperations {
* @return Converter in use
*/
ElasticsearchConverter getElasticsearchConverter();
/**
* @since 4.0
*/
RequestFactory getRequestFactory();
/**
* @param clazz
* @return the IndexCoordinates defined on the entity.
* @since 4.0
*/
default IndexCoordinates getIndexCoordinatesFor(Class<?> clazz) {
ElasticsearchPersistentEntity entity = getPersistentEntityFor(clazz);
return IndexCoordinates.of(entity.getIndexName()).withTypes(entity.getIndexType());
}
}

View File

@ -16,7 +16,6 @@
package org.springframework.data.elasticsearch.core;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@ -38,13 +37,18 @@ import org.springframework.util.StringUtils;
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 3.2
*/
@RequiredArgsConstructor
class EntityOperations {
private static final String ID_FIELD = "id";
public EntityOperations(
@NonNull MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> context) {
this.context = context;
}
private final @NonNull MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> context;
/**
@ -116,7 +120,7 @@ class EntityOperations {
*/
IndexCoordinates determineIndex(ElasticsearchPersistentEntity<?> persistentEntity, @Nullable String index,
@Nullable String type) {
return new IndexCoordinates(indexName(persistentEntity, index), typeName(persistentEntity, type));
return IndexCoordinates.of(indexName(persistentEntity, index)).withTypes(typeName(persistentEntity, type));
}
private static String indexName(@Nullable ElasticsearchPersistentEntity<?> entity, @Nullable String index) {
@ -615,14 +619,4 @@ class EntityOperations {
}
}
/**
* Value object encapsulating index name and index type.
*/
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
static class IndexCoordinates {
private final String indexName;
private final String typeName;
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2018-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core;
/**
* EsClient interface. Specify what client an ElasticSearchTemplate will return from getClient().
*
* @author Don Wellington
* @param <C>
*/
public interface EsClient<C> {
C getClient();
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.facet.FacetResult;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public interface FacetedPage<T> extends Page<T> {
boolean hasFacets();
List<FacetResult> getFacets();
FacetResult getFacet(String name);
}

View File

@ -1,171 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core;
import static java.util.Optional.*;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.ExtendedStats;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.data.elasticsearch.core.facet.FacetResult;
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequest;
import org.springframework.data.elasticsearch.core.facet.result.HistogramResult;
import org.springframework.data.elasticsearch.core.facet.result.IntervalUnit;
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
import org.springframework.data.elasticsearch.core.facet.result.StatisticalResult;
import org.springframework.data.elasticsearch.core.facet.result.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
/**
* Container for query result and facet results
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
* @author Philipp Kräutli
* @author Remco Zigterman
* @author Peter-Josef Meisch
*/
@Deprecated
public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedPage<T>, AggregatedPage<T> {
private List<FacetResult> facets;
private Map<String, FacetResult> mapOfFacets = new HashMap<>();
public FacetedPageImpl(List<T> content) {
super(content);
}
public FacetedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, ofNullable(pageable).orElse(Pageable.unpaged()), total);
}
@Override
public boolean hasFacets() {
processAggregations();
return facets != null && facets.size() > 0;
}
@Override
public List<FacetResult> getFacets() {
processAggregations();
return facets;
}
@Override
public FacetResult getFacet(String name) {
processAggregations();
return mapOfFacets.get(name);
}
private void addFacet(FacetResult facetResult) {
facets.add(facetResult);
mapOfFacets.put(facetResult.getName(), facetResult);
}
/**
* Lazy conversion from aggregation to old facets
*/
private void processAggregations() {
if (facets != null) {
return;
}
facets = new ArrayList<>();
Aggregations aggregations = getAggregations();
if (aggregations == null) {
return;
}
for (Aggregation agg : aggregations) {
processAggregation(agg);
}
}
private void processAggregation(Aggregation agg) {
if (agg instanceof Terms) {
processTermAggregation((Terms) agg);
}
if (agg instanceof Range) {
processRangeAggregation((Range) agg);
}
if (agg instanceof ExtendedStats) {
processExtendedStatsAggregation((ExtendedStats) agg);
}
if (agg instanceof Histogram) {
processHistogramAggregation((Histogram) agg);
}
}
private void processTermAggregation(Terms agg) {
List<Term> terms = new ArrayList<>();
for (Terms.Bucket t : agg.getBuckets()) {
terms.add(new Term(t.getKeyAsString(), t.getDocCount()));
}
addFacet(new TermResult(agg.getName(), terms, terms.size(), agg.getSumOfOtherDocCounts(), 0));
}
private void processRangeAggregation(Range agg) {
List<? extends Range.Bucket> buckets = ((Range) agg).getBuckets();
List<org.springframework.data.elasticsearch.core.facet.result.Range> ranges = new ArrayList<>();
for (Range.Bucket b : buckets) {
ExtendedStats rStats = b.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (rStats != null) {
Sum sum = b.getAggregations().get(RangeFacetRequest.RANGE_INTERNAL_SUM);
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(),
(Double) b.getTo(), b.getDocCount(), sum != null ? sum.getValue() : rStats.getSum(), rStats.getCount(),
rStats.getMin(), rStats.getMax()));
} else {
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(),
(Double) b.getTo(), b.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new RangeResult(agg.getName(), ranges));
}
private void processExtendedStatsAggregation(ExtendedStats agg) {
addFacet(new StatisticalResult(agg.getName(), agg.getCount(), agg.getMax(), agg.getMin(), agg.getAvg(),
agg.getStdDeviation(), agg.getSumOfSquares(), agg.getSum(), agg.getVariance()));
}
private void processHistogramAggregation(Histogram agg) {
List<IntervalUnit> intervals = new ArrayList<>();
for (Histogram.Bucket h : agg.getBuckets()) {
ExtendedStats hStats = h.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (hStats != null) {
intervals.add(new IntervalUnit(((ZonedDateTime) h.getKey()).toInstant().toEpochMilli(), h.getDocCount(),
h.getDocCount(), hStats.getSum(), hStats.getAvg(), hStats.getMin(), hStats.getMax()));
} else {
intervals.add(new IntervalUnit(((ZonedDateTime) h.getKey()).toInstant().toEpochMilli(), h.getDocCount(),
h.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new HistogramResult(agg.getName(), intervals));
}
}

View File

@ -0,0 +1,84 @@
/*
* 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.core;
import java.util.Arrays;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Immutable Value object encapsulating index name(s) and index type(s). Type names are supported but deprecated as
* Elasticsearch does not support types anymore.
*
* @author Mark Paluch
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 4.0
*/
public class IndexCoordinates {
private final String[] indexNames;
private final String[] typeNames;
public static IndexCoordinates of(String... indexNames) {
Assert.notNull(indexNames, "indexNames must not be null");
return new IndexCoordinates(indexNames, null);
}
private IndexCoordinates(String[] indexNames, @Nullable String[] typeNames) {
Assert.notEmpty(indexNames, "indexNames may not be null or empty");
this.indexNames = indexNames;
this.typeNames = typeNames != null ? typeNames : new String[] {};
}
/**
* Using Index types is deprecated in Elasticsearch.
*
* @param typeNames
* @return
*/
@Deprecated
public IndexCoordinates withTypes(String... typeNames) {
Assert.notEmpty(typeNames, "typeNames must not be null");
return new IndexCoordinates(this.indexNames, typeNames);
}
public String getIndexName() {
return indexNames[0];
}
public String[] getIndexNames() {
return Arrays.copyOf(indexNames, indexNames.length);
}
@Deprecated
@Nullable
public String getTypeName() {
return typeNames.length > 0 ? typeNames[0] : null;
}
@Deprecated
public String[] getTypeNames() {
return Arrays.copyOf(typeNames, typeNames.length);
}
@Override
public String toString() {
return "IndexCoordinates{" + "indexNames=" + Arrays.toString(indexNames) + ", typeNames="
+ Arrays.toString(typeNames) + '}';
}
}

View File

@ -56,7 +56,6 @@ import org.springframework.data.elasticsearch.NoSuchIndexException;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity;
import org.springframework.data.elasticsearch.core.EntityOperations.Entity;
import org.springframework.data.elasticsearch.core.EntityOperations.IndexCoordinates;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.DocumentAdapters;
@ -346,6 +345,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
searchSourceBuilder.size(pageable.getPageSize());
request.source(searchSourceBuilder);
request.source(searchSourceBuilder);
} else if (query.isLimiting()) {
searchSourceBuilder.from(0);
searchSourceBuilder.size(query.getMaxResults());
@ -356,10 +356,6 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
}
return request;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#count(Query, Class, String, String)
*/
/*
* (non-Javadoc)

View File

@ -0,0 +1,855 @@
/*
* 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.core;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.springframework.util.CollectionUtils.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetRequestBuilder;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetRequestBuilder;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.VersionType;
import org.elasticsearch.index.query.MoreLikeThisQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.ScoreSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Factory class to create Elasticsearch request instances from Spring Data Elasticsearch query objects.
*
* @author Peter-Josef Meisch
* @since 4.0
*/
class RequestFactory {
private final ElasticsearchConverter elasticsearchConverter;
public RequestFactory(ElasticsearchConverter elasticsearchConverter) {
this.elasticsearchConverter = elasticsearchConverter;
}
public IndicesAliasesRequest.AliasActions aliasAction(AliasQuery query, IndexCoordinates index) {
Assert.notNull(index, "No index defined for Alias");
Assert.notNull(query.getAliasName(), "No alias defined");
IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.add()
.alias(query.getAliasName()).index(index.getIndexName());
if (query.getFilterBuilder() != null) {
aliasAction.filter(query.getFilterBuilder());
} else if (query.getFilter() != null) {
aliasAction.filter(query.getFilter());
} else if (!StringUtils.isEmpty(query.getRouting())) {
aliasAction.routing(query.getRouting());
} else if (!StringUtils.isEmpty(query.getSearchRouting())) {
aliasAction.searchRouting(query.getSearchRouting());
} else if (!StringUtils.isEmpty(query.getIndexRouting())) {
aliasAction.indexRouting(query.getIndexRouting());
}
return aliasAction;
}
public BulkRequest bulkRequest(List<?> queries, BulkOptions bulkOptions, IndexCoordinates index) {
BulkRequest bulkRequest = new BulkRequest();
if (bulkOptions.getTimeout() != null) {
bulkRequest.timeout(bulkOptions.getTimeout());
}
if (bulkOptions.getRefreshPolicy() != null) {
bulkRequest.setRefreshPolicy(bulkOptions.getRefreshPolicy());
}
if (bulkOptions.getWaitForActiveShards() != null) {
bulkRequest.waitForActiveShards(bulkOptions.getWaitForActiveShards());
}
if (bulkOptions.getPipeline() != null) {
bulkRequest.pipeline(bulkOptions.getPipeline());
}
if (bulkOptions.getRoutingId() != null) {
bulkRequest.routing(bulkOptions.getRoutingId());
}
queries.forEach(query -> {
if (query instanceof IndexQuery) {
bulkRequest.add(indexRequest((IndexQuery) query, index));
} else if (query instanceof UpdateQuery) {
bulkRequest.add(updateRequest((UpdateQuery) query, index));
}
});
return bulkRequest;
}
public BulkRequestBuilder bulkRequestBuilder(Client client, List<?> queries, BulkOptions bulkOptions,
IndexCoordinates index) {
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
if (bulkOptions.getTimeout() != null) {
bulkRequestBuilder.setTimeout(bulkOptions.getTimeout());
}
if (bulkOptions.getRefreshPolicy() != null) {
bulkRequestBuilder.setRefreshPolicy(bulkOptions.getRefreshPolicy());
}
if (bulkOptions.getWaitForActiveShards() != null) {
bulkRequestBuilder.setWaitForActiveShards(bulkOptions.getWaitForActiveShards());
}
if (bulkOptions.getPipeline() != null) {
bulkRequestBuilder.pipeline(bulkOptions.getPipeline());
}
if (bulkOptions.getRoutingId() != null) {
bulkRequestBuilder.routing(bulkOptions.getRoutingId());
}
queries.forEach(query -> {
if (query instanceof IndexQuery) {
bulkRequestBuilder.add(indexRequestBuilder(client, (IndexQuery) query, index));
} else if (query instanceof UpdateQuery) {
bulkRequestBuilder.add(updateRequestBuilderFor(client, (UpdateQuery) query, index));
}
});
return bulkRequestBuilder;
}
public CreateIndexRequest createIndexRequest(String indexName, Object settings) {
CreateIndexRequest request = new CreateIndexRequest(indexName);
if (settings instanceof String) {
request.settings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE);
} else if (settings instanceof Map) {
request.settings((Map) settings);
} else if (settings instanceof XContentBuilder) {
request.settings((XContentBuilder) settings);
}
return request;
}
public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, Object settings) {
CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName);
if (settings instanceof String) {
createIndexRequestBuilder.setSettings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE);
} else if (settings instanceof Map) {
createIndexRequestBuilder.setSettings((Map) settings);
} else if (settings instanceof XContentBuilder) {
createIndexRequestBuilder.setSettings((XContentBuilder) settings);
}
return createIndexRequestBuilder;
}
public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexCoordinates index) {
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) //
.setDocTypes(index.getTypeNames()) //
.setQuery(deleteQuery.getQuery()) //
.setAbortOnVersionConflict(false) //
.setRefresh(true);
if (deleteQuery.getPageSize() != null)
deleteByQueryRequest.setBatchSize(deleteQuery.getPageSize());
if (deleteQuery.getScrollTimeInMillis() != null)
deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis()));
return deleteByQueryRequest;
}
public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, DeleteQuery deleteQuery,
IndexCoordinates index) {
DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) //
.source(index.getIndexNames()) //
.filter(deleteQuery.getQuery()) //
.abortOnVersionConflict(false) //
.refresh(true);
SearchRequestBuilder source = requestBuilder.source() //
.setTypes(index.getTypeNames());
if (deleteQuery.getScrollTimeInMillis() != null)
source.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis()));
return requestBuilder;
}
public GetRequest getRequest(GetQuery query, IndexCoordinates index) {
return new GetRequest(index.getIndexName(), index.getTypeName(), query.getId());
}
public GetRequestBuilder getRequestBuilder(Client client, GetQuery query, IndexCoordinates index) {
return client.prepareGet(index.getIndexName(), index.getTypeName(), query.getId());
}
public HighlightBuilder highlightBuilder(Query query) {
HighlightBuilder highlightBuilder = null;
if (query instanceof NativeSearchQuery) {
NativeSearchQuery searchQuery = (NativeSearchQuery) query;
if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) {
highlightBuilder = searchQuery.getHighlightBuilder();
if (highlightBuilder == null) {
highlightBuilder = new HighlightBuilder();
}
if (searchQuery.getHighlightFields() != null) {
for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) {
highlightBuilder.field(highlightField);
}
}
}
}
return highlightBuilder;
}
public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) {
String indexName = index.getIndexName();
String type = index.getTypeName();
IndexRequest indexRequest;
if (query.getObject() != null) {
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId();
// If we have a query id and a document id, do not ask ES to generate one.
if (id != null) {
indexRequest = new IndexRequest(indexName, type, id);
} else {
indexRequest = new IndexRequest(indexName, type);
}
indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE);
} else if (query.getSource() != null) {
indexRequest = new IndexRequest(indexName, type, query.getId()).source(query.getSource(),
Requests.INDEX_CONTENT_TYPE);
} else {
throw new ElasticsearchException(
"object or source is null, failed to index the document [id: " + query.getId() + "]");
}
if (query.getVersion() != null) {
indexRequest.version(query.getVersion());
VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass());
indexRequest.versionType(versionType);
}
return indexRequest;
}
public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, IndexCoordinates index) {
String indexName = index.getIndexName();
String type = index.getTypeName();
IndexRequestBuilder indexRequestBuilder;
if (query.getObject() != null) {
String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId();
// If we have a query id and a document id, do not ask ES to generate one.
if (id != null) {
indexRequestBuilder = client.prepareIndex(indexName, type, id);
} else {
indexRequestBuilder = client.prepareIndex(indexName, type);
}
indexRequestBuilder.setSource(elasticsearchConverter.mapObject(query.getObject()).toJson(),
Requests.INDEX_CONTENT_TYPE);
} else if (query.getSource() != null) {
indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource(),
Requests.INDEX_CONTENT_TYPE);
} else {
throw new ElasticsearchException(
"object or source is null, failed to index the document [id: " + query.getId() + "]");
}
if (query.getVersion() != null) {
indexRequestBuilder.setVersion(query.getVersion());
VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass());
indexRequestBuilder.setVersionType(versionType);
}
return indexRequestBuilder;
}
public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) {
MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), index.getTypeName(),
query.getId());
MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders
.moreLikeThisQuery(new MoreLikeThisQueryBuilder.Item[] { item });
if (query.getMinTermFreq() != null) {
moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq());
}
if (query.getMaxQueryTerms() != null) {
moreLikeThisQueryBuilder.maxQueryTerms(query.getMaxQueryTerms());
}
if (!isEmpty(query.getStopWords())) {
moreLikeThisQueryBuilder.stopWords(query.getStopWords());
}
if (query.getMinDocFreq() != null) {
moreLikeThisQueryBuilder.minDocFreq(query.getMinDocFreq());
}
if (query.getMaxDocFreq() != null) {
moreLikeThisQueryBuilder.maxDocFreq(query.getMaxDocFreq());
}
if (query.getMinWordLen() != null) {
moreLikeThisQueryBuilder.minWordLength(query.getMinWordLen());
}
if (query.getMaxWordLen() != null) {
moreLikeThisQueryBuilder.maxWordLength(query.getMaxWordLen());
}
if (query.getBoostTerms() != null) {
moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms());
}
return moreLikeThisQueryBuilder;
}
public SearchRequest searchRequest(Query query, @Nullable Class<?> clazz, IndexCoordinates index) {
SearchRequest searchRequest = prepareSearchRequest(query, clazz, index);
QueryBuilder elasticsearchQuery = getQuery(query);
QueryBuilder elasticsearchFilter = getFilter(query);
if (elasticsearchQuery != null) {
searchRequest.source().query(elasticsearchQuery);
} else {
searchRequest.source().query(QueryBuilders.matchAllQuery());
}
if (elasticsearchFilter != null) {
searchRequest.source().postFilter(elasticsearchFilter);
}
return searchRequest;
}
public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nullable Class<?> clazz,
IndexCoordinates index) {
SearchRequestBuilder searchRequestBuilder = prepareSearchRequestBuilder(query, client, clazz, index);
QueryBuilder elasticsearchQuery = getQuery(query);
QueryBuilder elasticsearchFilter = getFilter(query);
if (elasticsearchQuery != null) {
searchRequestBuilder.setQuery(elasticsearchQuery);
} else {
searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery());
}
if (elasticsearchFilter != null) {
searchRequestBuilder.setPostFilter(elasticsearchFilter);
}
return searchRequestBuilder;
}
public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) {
Assert.notNull(query.getId(), "No Id define for Query");
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
UpdateRequest queryUpdateRequest = query.getUpdateRequest();
UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), index.getTypeName(), query.getId()) //
.routing(queryUpdateRequest.routing()) //
.retryOnConflict(queryUpdateRequest.retryOnConflict()) //
.timeout(queryUpdateRequest.timeout()) //
.waitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
.setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) //
.waitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
.scriptedUpsert(queryUpdateRequest.scriptedUpsert()) //
.docAsUpsert(queryUpdateRequest.docAsUpsert());
if (query.DoUpsert()) {
updateRequest.docAsUpsert(true);
}
if (queryUpdateRequest.script() != null) {
updateRequest.script(queryUpdateRequest.script());
}
if (queryUpdateRequest.doc() != null) {
updateRequest.doc(queryUpdateRequest.doc());
}
if (queryUpdateRequest.upsertRequest() != null) {
updateRequest.upsert(queryUpdateRequest.upsertRequest());
}
if (queryUpdateRequest.fetchSource() != null) {
updateRequest.fetchSource(queryUpdateRequest.fetchSource());
}
return updateRequest;
}
public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery query, IndexCoordinates index) {
Assert.notNull(query.getId(), "No Id define for Query");
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
UpdateRequest queryUpdateRequest = query.getUpdateRequest();
UpdateRequestBuilder updateRequestBuilder = client
.prepareUpdate(index.getIndexName(), index.getTypeName(), query.getId()) //
.setRouting(queryUpdateRequest.routing()) //
.setRetryOnConflict(queryUpdateRequest.retryOnConflict()) //
.setTimeout(queryUpdateRequest.timeout()) //
.setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
.setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) //
.setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) //
.setScriptedUpsert(queryUpdateRequest.scriptedUpsert()) //
.setDocAsUpsert(queryUpdateRequest.docAsUpsert());
if (query.DoUpsert()) {
updateRequestBuilder.setDocAsUpsert(true);
}
if (queryUpdateRequest.script() != null) {
updateRequestBuilder.setScript(queryUpdateRequest.script());
}
if (queryUpdateRequest.doc() != null) {
updateRequestBuilder.setDoc(queryUpdateRequest.doc());
}
if (queryUpdateRequest.upsertRequest() != null) {
updateRequestBuilder.setUpsert(queryUpdateRequest.upsertRequest());
}
FetchSourceContext fetchSourceContext = queryUpdateRequest.fetchSource();
if (fetchSourceContext != null) {
updateRequestBuilder.setFetchSource(fetchSourceContext.includes(), fetchSourceContext.excludes());
}
return updateRequestBuilder;
}
private SearchRequest prepareSearchRequest(Query query, @Nullable Class<?> clazz, IndexCoordinates index) {
return prepareSearchRequest(query, Optional.empty(), clazz, index);
}
public PutMappingRequest putMappingRequest(IndexCoordinates index, Object mapping) {
PutMappingRequest request = new PutMappingRequest(index.getIndexName()).type(index.getTypeName());
if (mapping instanceof String) {
request.source(String.valueOf(mapping), XContentType.JSON);
} else if (mapping instanceof Map) {
request.source((Map) mapping);
} else if (mapping instanceof XContentBuilder) {
request.source((XContentBuilder) mapping);
}
return request;
}
public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Object mapping) {
PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(index.getIndexName())
.setType(index.getTypeName());
if (mapping instanceof String) {
requestBuilder.setSource(String.valueOf(mapping), XContentType.JSON);
} else if (mapping instanceof Map) {
requestBuilder.setSource((Map) mapping);
} else if (mapping instanceof XContentBuilder) {
requestBuilder.setSource((XContentBuilder) mapping);
}
return requestBuilder;
}
public MultiGetRequest multiGetRequest(Query query, IndexCoordinates index) {
MultiGetRequest multiGetRequest = new MultiGetRequest();
getMultiRequestItems(query, index).forEach(multiGetRequest::add);
return multiGetRequest;
}
public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, IndexCoordinates index) {
MultiGetRequestBuilder multiGetRequestBuilder = client.prepareMultiGet();
getMultiRequestItems(searchQuery, index).forEach(multiGetRequestBuilder::add);
return multiGetRequestBuilder;
}
private List<MultiGetRequest.Item> getMultiRequestItems(Query searchQuery, IndexCoordinates index) {
List<MultiGetRequest.Item> items = new ArrayList<>();
if (!isEmpty(searchQuery.getFields())) {
searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null));
}
for (String id : searchQuery.getIds()) {
MultiGetRequest.Item item = new MultiGetRequest.Item(index.getIndexName(), index.getTypeName(), id);
if (searchQuery.getRoute() != null) {
item = item.routing(searchQuery.getRoute());
}
items.add(item);
}
return items;
}
private SearchRequest prepareSearchRequest(Query query, Optional<QueryBuilder> builder, @Nullable Class<?> clazz,
IndexCoordinates index) {
Assert.notNull(index.getIndexNames(), "No index defined for Query");
Assert.notEmpty(index.getIndexNames(), "No index defined for Query");
Assert.notNull(index.getTypeNames(), "No type defined for Query");
int startRecord = 0;
SearchRequest request = new SearchRequest(index.getIndexNames());
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
request.types(index.getTypeNames());
sourceBuilder.version(true);
sourceBuilder.trackScores(query.getTrackScores());
builder.ifPresent(sourceBuilder::query);
if (query.getSourceFilter() != null) {
SourceFilter sourceFilter = query.getSourceFilter();
sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
}
if (query.getPageable().isPaged()) {
startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
sourceBuilder.size(query.getPageable().getPageSize());
}
sourceBuilder.from(startRecord);
if (!query.getFields().isEmpty()) {
sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null);
}
if (query.getIndicesOptions() != null) {
request.indicesOptions(query.getIndicesOptions());
}
if (query.isLimiting()) {
sourceBuilder.size(query.getMaxResults());
}
if (query.getMinScore() > 0) {
sourceBuilder.minScore(query.getMinScore());
}
if (query.getPreference() != null) {
request.preference(query.getPreference());
}
if (query.getSearchType() != null) {
request.searchType(query.getSearchType());
}
prepareSort(query, sourceBuilder, getPersistentEntity(clazz));
HighlightBuilder highlightBuilder = highlightBuilder(query);
if (highlightBuilder != null) {
sourceBuilder.highlighter(highlightBuilder);
}
if (query instanceof NativeSearchQuery) {
NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query;
if (!nativeSearchQuery.getScriptFields().isEmpty()) {
for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) {
sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script());
}
}
if (nativeSearchQuery.getCollapseBuilder() != null) {
sourceBuilder.collapse(nativeSearchQuery.getCollapseBuilder());
}
}
request.source(sourceBuilder);
return request;
}
private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client,
@Nullable ElasticsearchPersistentEntity<?> entity, IndexCoordinates index) {
Assert.notNull(index.getIndexNames(), "No index defined for Query");
Assert.notEmpty(index.getIndexNames(), "No index defined for Query");
Assert.notNull(index.getTypeNames(), "No type defined for Query");
int startRecord = 0;
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index.getIndexNames()) //
.setSearchType(query.getSearchType()) //
.setTypes(index.getTypeNames()) //
.setVersion(true) //
.setTrackScores(query.getTrackScores());
if (query.getSourceFilter() != null) {
SourceFilter sourceFilter = query.getSourceFilter();
searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes());
}
if (query.getPageable().isPaged()) {
startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
searchRequestBuilder.setSize(query.getPageable().getPageSize());
}
searchRequestBuilder.setFrom(startRecord);
if (!query.getFields().isEmpty()) {
searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null);
}
if (query.getIndicesOptions() != null) {
searchRequestBuilder.setIndicesOptions(query.getIndicesOptions());
}
if (query.isLimiting()) {
searchRequestBuilder.setSize(query.getMaxResults());
}
if (query.getMinScore() > 0) {
searchRequestBuilder.setMinScore(query.getMinScore());
}
if (query.getPreference() != null) {
searchRequestBuilder.setPreference(query.getPreference());
}
prepareSort(query, searchRequestBuilder, entity);
HighlightBuilder highlightBuilder = highlightBuilder(query);
if (highlightBuilder != null) {
searchRequestBuilder.highlighter(highlightBuilder);
}
if (query instanceof NativeSearchQuery) {
prepareNativeSearch(searchRequestBuilder, (NativeSearchQuery) query);
}
return searchRequestBuilder;
}
private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, NativeSearchQuery nativeSearchQuery) {
if (!isEmpty(nativeSearchQuery.getScriptFields())) {
for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) {
searchRequestBuilder.addScriptField(scriptedField.fieldName(), scriptedField.script());
}
}
if (nativeSearchQuery.getCollapseBuilder() != null) {
searchRequestBuilder.setCollapse(nativeSearchQuery.getCollapseBuilder());
}
if (!isEmpty(nativeSearchQuery.getIndicesBoost())) {
for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) {
searchRequestBuilder.addIndexBoost(indexBoost.getIndexName(), indexBoost.getBoost());
}
}
if (!isEmpty(nativeSearchQuery.getAggregations())) {
for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) {
searchRequestBuilder.addAggregation(aggregationBuilder);
}
}
}
private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class<?> clazz,
IndexCoordinates index) {
return prepareSearchRequestBuilder(query, client, getPersistentEntity(clazz), index);
}
private void prepareSort(Query query, SearchSourceBuilder sourceBuilder,
@Nullable ElasticsearchPersistentEntity<?> entity) {
if (query.getSort() != null) {
query.getSort().forEach(order -> sourceBuilder.sort(getSortBuilder(order, entity)));
}
if (query instanceof NativeSearchQuery) {
NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query;
List<SortBuilder> sorts = nativeSearchQuery.getElasticsearchSorts();
if (sorts != null) {
sorts.forEach(sourceBuilder::sort);
}
}
}
private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder,
@Nullable ElasticsearchPersistentEntity<?> entity) {
if (query.getSort() != null) {
query.getSort().forEach(order -> searchRequestBuilder.addSort(getSortBuilder(order, entity)));
}
if (query instanceof NativeSearchQuery) {
NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query;
List<SortBuilder> sorts = nativeSearchQuery.getElasticsearchSorts();
if (sorts != null) {
sorts.forEach(searchRequestBuilder::addSort);
}
}
}
private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchPersistentEntity<?> entity) {
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
if (ScoreSortBuilder.NAME.equals(order.getProperty())) {
return SortBuilders //
.scoreSort() //
.order(sortOrder);
} else {
ElasticsearchPersistentProperty property = (entity != null) //
? entity.getPersistentProperty(order.getProperty()) //
: null;
String fieldName = property != null ? property.getFieldName() : order.getProperty();
FieldSortBuilder sort = SortBuilders //
.fieldSort(fieldName) //
.order(sortOrder);
if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) {
sort.missing("_first");
} else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
sort.missing("_last");
}
return sort;
}
}
private QueryBuilder getQuery(Query query) {
QueryBuilder elasticsearchQuery;
if (query instanceof NativeSearchQuery) {
NativeSearchQuery searchQuery = (NativeSearchQuery) query;
elasticsearchQuery = searchQuery.getQuery();
} else if (query instanceof CriteriaQuery) {
CriteriaQuery criteriaQuery = (CriteriaQuery) query;
elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria());
} else if (query instanceof StringQuery) {
StringQuery stringQuery = (StringQuery) query;
elasticsearchQuery = wrapperQuery(stringQuery.getSource());
} else {
throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName());
}
return elasticsearchQuery;
}
public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) {
IndicesAliasesRequest.AliasActions aliasAction = aliasAction(query, index);
IndicesAliasesRequest request = new IndicesAliasesRequest();
request.addAliasAction(aliasAction);
return request;
}
public IndicesAliasesRequest indicesRemoveAliasesRequest(AliasQuery query, IndexCoordinates index) {
IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() //
.index(index.getIndexName()) //
.alias(query.getAliasName());
return Requests.indexAliasesRequest() //
.addAliasAction(aliasAction);
}
private QueryBuilder getFilter(Query query) {
QueryBuilder elasticsearchFilter;
if (query instanceof NativeSearchQuery) {
NativeSearchQuery searchQuery = (NativeSearchQuery) query;
elasticsearchFilter = searchQuery.getFilter();
} else if (query instanceof CriteriaQuery) {
CriteriaQuery criteriaQuery = (CriteriaQuery) query;
elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria());
} else if (query instanceof StringQuery) {
elasticsearchFilter = null;
} else {
throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName());
}
return elasticsearchFilter;
}
@Nullable
private ElasticsearchPersistentEntity<?> getPersistentEntity(@Nullable Class<?> clazz) {
return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null;
}
private String getPersistentEntityId(Object entity) {
Object identifier = elasticsearchConverter.getMappingContext() //
.getRequiredPersistentEntity(entity.getClass()) //
.getIdentifierAccessor(entity).getIdentifier();
if (identifier != null) {
return identifier.toString();
}
return null;
}
private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) {
if (clazz != null) {
return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz).getVersionType();
}
return VersionType.EXTERNAL;
}
private String[] toArray(List<String> values) {
String[] valuesAsArray = new String[values.size()];
return values.toArray(valuesAsArray);
}
}

View File

@ -2,15 +2,15 @@ package org.springframework.data.elasticsearch.core.aggregation;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.elasticsearch.core.FacetedPage;
import org.springframework.data.elasticsearch.core.ScoredPage;
import org.springframework.data.elasticsearch.core.ScrolledPage;
/**
* @author Petar Tahchiev
* @author Sascha Woo
* @author Peter-Josef Meisch
*/
public interface AggregatedPage<T> extends FacetedPage<T>, ScrolledPage<T>, ScoredPage<T> {
public interface AggregatedPage<T> extends ScrolledPage<T>, ScoredPage<T> {
boolean hasAggregations();

View File

@ -15,12 +15,14 @@
*/
package org.springframework.data.elasticsearch.core.aggregation.impl;
import static java.util.Optional.*;
import java.util.List;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.FacetedPageImpl;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
@ -31,12 +33,16 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentRespon
* @author Sascha Woo
* @author Peter-Josef Meisch
*/
public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements AggregatedPage<T> {
public class AggregatedPageImpl<T> extends PageImpl<T> implements AggregatedPage<T> {
private Aggregations aggregations;
private String scrollId;
private float maxScore;
private static Pageable pageableOrUnpaged(Pageable pageable) {
return ofNullable(pageable).orElse(Pageable.unpaged());
}
public AggregatedPageImpl(List<T> content) {
super(content);
}
@ -57,26 +63,26 @@ public class AggregatedPageImpl<T> extends FacetedPageImpl<T> implements Aggrega
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total) {
super(content, pageable, total);
super(content, pageableOrUnpaged(pageable), total);
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, float maxScore) {
super(content, pageable, total);
super(content, pageableOrUnpaged(pageable), total);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) {
super(content, pageable, total);
super(content, pageableOrUnpaged(pageable), total);
this.scrollId = scrollId;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId, float maxScore) {
this(content, pageable, total, scrollId);
this(content, pageableOrUnpaged(pageable), total, scrollId);
this.maxScore = maxScore;
}
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) {
super(content, pageable, total);
super(content, pageableOrUnpaged(pageable), total);
this.aggregations = aggregations;
}

View File

@ -1,50 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
import org.springframework.util.Assert;
/**
* @author Artur Konczak
*/
@Deprecated
public abstract class AbstractFacetRequest implements FacetRequest {
public static final String INTERNAL_STATS = "internal-stats";
private String name;
private boolean applyQueryFilter;
public AbstractFacetRequest(String name) {
Assert.hasText(name, "Facet can't be null or empty !!!");
this.name = name;
}
protected String getName() {
return name;
}
public void setApplyQueryFilter(boolean applyQueryFilter) {
this.applyQueryFilter = applyQueryFilter;
}
@Override
public boolean applyQueryFilter() {
return applyQueryFilter;
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
import org.springframework.util.Assert;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class AbstractFacetResult implements FacetResult {
private final String name;
private final FacetType type;
protected AbstractFacetResult(String name, FacetType type) {
Assert.hasText(name, "Facet name can't be null and should have a value");
this.name = name;
this.type = type;
}
@Override
public String getName() {
return name;
}
@Override
public FacetType getType() {
return type;
}
}

View File

@ -1,33 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
/**
* @author Artur Koczak
*/
@Deprecated
public interface FacetRequest {
public static final String FIELD_UNTOUCHED = "untouched";
public static final String FIELD_SORT = "sort";
AbstractAggregationBuilder getFacet();
boolean applyQueryFilter();
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
/**
* Generic interface for all facets
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public interface FacetResult {
String getName();
FacetType getType();
}

View File

@ -1,27 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
/**
* @author Artur Konczak
* @author Petar Tahchiev
*/
@Deprecated
public enum FacetType {
term, range, histogram, statistical
}

View File

@ -1,72 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public class HistogramFacetRequest extends AbstractFacetRequest {
private String field;
private long interval;
private DateHistogramInterval timeUnit;
public HistogramFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setInterval(long interval) {
this.interval = interval;
}
public void setTimeUnit(DateHistogramInterval timeUnit) {
this.timeUnit = timeUnit;
}
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
Assert.isTrue(!StringUtils.isEmpty(field), "Please select field on which to build the facet !!!");
Assert.isTrue(interval > 0, "Please provide interval as positive value greater them zero !!!");
DateHistogramAggregationBuilder dateHistogramBuilder = AggregationBuilders.dateHistogram(getName());
dateHistogramBuilder.field(field);
if (timeUnit != null) {
dateHistogramBuilder.dateHistogramInterval(timeUnit);
} else {
dateHistogramBuilder.interval(interval);
}
dateHistogramBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field));
return dateHistogramBuilder;
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Artur Konczak
*/
@Deprecated
public class HistogramFacetRequestBuilder {
HistogramFacetRequest result;
public HistogramFacetRequestBuilder(String name) {
result = new HistogramFacetRequest(name);
}
public HistogramFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public HistogramFacetRequestBuilder interval(long interval) {
result.setInterval(interval);
return this;
}
public HistogramFacetRequestBuilder timeUnit(DateHistogramInterval timeUnit) {
result.setTimeUnit(timeUnit);
return this;
}
public FacetRequest build() {
return result;
}
public HistogramFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public class NativeFacetRequest implements FacetRequest {
public NativeFacetRequest() {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
@Override
public AbstractAggregationBuilder getFacet() {
return null;
}
@Override
public boolean applyQueryFilter() {
return false;
}
}

View File

@ -1,132 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import java.util.ArrayList;
import java.util.List;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Range facet for numeric fields
*
* @author Artur Konczak
* @author Akos Bordas
*/
@Deprecated
public class RangeFacetRequest extends AbstractFacetRequest {
public static final String RANGE_INTERNAL_SUM = "range-internal-sum";
private String field;
private String keyField;
private String valueField;
private List<Entry> entries = new ArrayList<>();
public RangeFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setFields(String keyField, String valueField) {
this.keyField = keyField;
this.valueField = valueField;
}
public void range(Double from, Double to) {
entries.add(new DoubleEntry(from, to));
}
public void range(String from, String to) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
public void addRange(Double from, Double to) {
entries.add(new DoubleEntry(from, to));
}
public void addRange(String from, String to) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
@Override
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
RangeAggregationBuilder rangeBuilder = AggregationBuilders.range(getName());
final String field = !StringUtils.isEmpty(keyField) ? keyField : this.field;
rangeBuilder.field(field);
for (Entry entry : entries) {
DoubleEntry doubleEntry = (DoubleEntry) entry;
rangeBuilder.addRange(validateValue(doubleEntry.getFrom(), Double.NEGATIVE_INFINITY), validateValue(doubleEntry.getTo(), Double.POSITIVE_INFINITY));
}
rangeBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field));
if(!StringUtils.isEmpty(valueField)){
rangeBuilder.subAggregation(AggregationBuilders.sum(RANGE_INTERNAL_SUM).field(valueField));
}
return rangeBuilder;
}
private double validateValue(Double value, double defaultValue) {
return value == null ? defaultValue : value;
}
static class DoubleEntry extends Entry<Double> {
DoubleEntry(Double from, Double to) {
super(from, to);
}
}
static class StringEntry extends Entry<String> {
StringEntry(String from, String to) {
super(from, to);
}
}
static class Entry<T> {
T from;
T to;
Entry(T from, T to) {
this.from = from;
this.to = to;
}
public T getFrom() {
return from;
}
public T getTo() {
return to;
}
}
}

View File

@ -1,85 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* Basic range facet
*
* @author Artur Konczak
*/
@Deprecated
public class RangeFacetRequestBuilder {
RangeFacetRequest result;
public RangeFacetRequestBuilder(String name) {
result = new RangeFacetRequest(name);
}
public RangeFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public RangeFacetRequestBuilder fields(String keyField, String valueField) {
result.setFields(keyField, valueField);
return this;
}
public RangeFacetRequestBuilder range(double from, double to) {
result.range(from, to);
return this;
}
public RangeFacetRequestBuilder range(String from, String to) {
result.range(from, to);
return this;
}
public RangeFacetRequestBuilder from(double from) {
result.range(from, null);
return this;
}
public RangeFacetRequestBuilder to(double to) {
result.range(null, to);
return this;
}
public RangeFacetRequestBuilder from(String from) {
result.range(from, null);
return this;
}
public RangeFacetRequestBuilder to(String to) {
result.range(null, to);
return this;
}
public RangeFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalFacetRequest extends AbstractFacetRequest {
private String field;
private String[] fields;
public StatisticalFacetRequest(String name) {
super(name);
}
public void setField(String field) {
this.field = field;
}
public void setFields(String... fields) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
}
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
Assert.isTrue(!StringUtils.isEmpty(field) && fields == null, "Please select field or fields on which to build the facets !!!");
return AggregationBuilders.extendedStats(getName()).field(field);
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalFacetRequestBuilder {
StatisticalFacetRequest result;
public StatisticalFacetRequestBuilder(String name) {
result = new StatisticalFacetRequest(name);
}
public StatisticalFacetRequestBuilder field(String field) {
result.setField(field);
return this;
}
public StatisticalFacetRequestBuilder fields(String... fields) {
result.setFields(fields);
return this;
}
public StatisticalFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}

View File

@ -1,27 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
/**
* @author Artur Konczak
* @author Mohsin Husen
*/
@Deprecated
public enum TermFacetOrder {
ascTerm, descTerm, ascCount, descCount;
}

View File

@ -1,109 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.apache.lucene.util.automaton.RegExp;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.IncludeExclude;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Term facet
*
* @author Artur Konczak
* @author Ilkang Na
*/
@Deprecated
public class TermFacetRequest extends AbstractFacetRequest {
private String[] fields;
private String[] excludeTerms;
private int size = 10;
private TermFacetOrder order = TermFacetOrder.descCount;
private boolean allTerms = false;
private String regex = null;
public TermFacetRequest(String name) {
super(name);
}
public void setFields(String... fields) {
Assert.isTrue(!ObjectUtils.isEmpty(fields), "Term agg need one field only");
Assert.isTrue(fields.length == 1, "Term agg need one field only");
this.fields = fields;
}
public void setSize(int size) {
Assert.isTrue(size >= 0, "Size should be bigger then zero !!!");
this.size = size;
}
public void setOrder(TermFacetOrder order) {
this.order = order;
}
public void setExcludeTerms(String... excludeTerms) {
this.excludeTerms = excludeTerms;
}
public void setAllTerms(boolean allTerms) {
this.allTerms = allTerms;
}
public void setRegex(String regex) {
this.regex = regex;
}
@Override
public AbstractAggregationBuilder getFacet() {
Assert.notEmpty(fields, "Please select at last one field !!!");
final TermsAggregationBuilder termsBuilder = AggregationBuilders.terms(getName()).field(fields[0]).size(this.size);
switch (order) {
case descTerm:
termsBuilder.order(BucketOrder.key(false));
break;
case ascTerm:
termsBuilder.order(BucketOrder.key(true));
break;
case descCount:
termsBuilder.order(BucketOrder.count(false));
break;
default:
termsBuilder.order(BucketOrder.count(true));
}
if (!ObjectUtils.isEmpty(excludeTerms)) {
termsBuilder.includeExclude(new IncludeExclude(null, excludeTerms));
}
if (allTerms) {
termsBuilder.size(Integer.MAX_VALUE);
}
if (!StringUtils.isEmpty(regex)) {
termsBuilder.includeExclude(new IncludeExclude(new RegExp(regex), null));
}
return termsBuilder;
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.request;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* Basic term facet
*
* @author Artur Konczak
*/
@Deprecated
public class TermFacetRequestBuilder {
private TermFacetRequest result;
public TermFacetRequestBuilder(String name) {
result = new TermFacetRequest(name);
}
public TermFacetRequestBuilder fields(String... fields) {
result.setFields(fields);
return this;
}
public TermFacetRequestBuilder size(int size) {
result.setSize(size);
return this;
}
public TermFacetRequestBuilder excludeTerms(String... terms) {
result.setExcludeTerms(terms);
return this;
}
public TermFacetRequestBuilder allTerms() {
result.setAllTerms(true);
return this;
}
public TermFacetRequestBuilder regex(String regex) {
result.setRegex(regex);
return this;
}
public TermFacetRequestBuilder ascTerm() {
result.setOrder(TermFacetOrder.ascTerm);
return this;
}
public TermFacetRequestBuilder descTerm() {
result.setOrder(TermFacetOrder.descTerm);
return this;
}
public TermFacetRequestBuilder ascCount() {
result.setOrder(TermFacetOrder.ascCount);
return this;
}
public TermFacetRequestBuilder descCount() {
result.setOrder(TermFacetOrder.descCount);
return this;
}
public TermFacetRequestBuilder applyQueryFilter() {
result.setApplyQueryFilter(true);
return this;
}
public FacetRequest build() {
return result;
}
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* @author Artur Konczak
*/
@Deprecated
public class HistogramResult extends AbstractFacetResult {
private List<IntervalUnit> terms;
public HistogramResult(String name, List<IntervalUnit> terms) {
super(name, FacetType.term);
this.terms = terms;
}
public List<IntervalUnit> getIntervalUnit() {
return terms;
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Single term
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class IntervalUnit {
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long key;
long count;
long totalCount;
double total;
double mean;
double min;
double max;
public IntervalUnit(long key, long count, long totalCount, double total, double mean, double min, double max) {
this.key = key;
this.count = count;
this.totalCount = totalCount;
this.total = total;
this.mean = mean;
this.min = min;
this.max = max;
}
public long getKey() {
return key;
}
public long getCount() {
return count;
}
public long getTotalCount() {
return totalCount;
}
public double getTotal() {
return total;
}
public double getMean() {
return mean;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
@Override
public String toString() {
return "IntervalUnit{" +
"key=" + format.format(new Date(key)) +
", count=" + count +
", totalCount=" + totalCount +
", total=" + total +
", mean=" + mean +
", min=" + min +
", max=" + max +
'}';
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
/**
* Single range
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class Range {
private Double from;
private Double to;
private long count;
private double total;
private double totalCount;
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
public Range(Double from, Double to, long count, double total, double totalCount, double min, double max) {
this.from = from;
this.to = to;
this.count = count;
this.total = total;
this.totalCount = totalCount;
this.min = min;
this.max = max;
}
public Double getFrom() {
return from;
}
public Double getTo() {
return to;
}
/**
* Return number of documents in range
*
* @return
*/
public long getCount() {
return count;
}
public double getTotal() {
return total;
}
public double getTotalCount() {
return totalCount;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* Basic term facet result
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class RangeResult extends AbstractFacetResult {
private List<Range> ranges;
public RangeResult(String name, List<Range> ranges) {
super(name, FacetType.range);
this.ranges = ranges;
}
public List<Range> getRanges() {
return ranges;
}
}

View File

@ -1,86 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* @author Petar Tahchiev
*/
@Deprecated
public class StatisticalResult extends AbstractFacetResult {
private long count;
private double max;
private double min;
private double mean;
private double stdDeviation;
private double sumOfSquares;
private double total;
private double variance;
public StatisticalResult(String name, long count, double max, double min, double mean, double stdDeviation, double sumOfSquares, double total, double variance) {
super(name, FacetType.statistical);
this.count = count;
this.max = max;
this.min = min;
this.mean = mean;
this.stdDeviation = stdDeviation;
this.sumOfSquares = sumOfSquares;
this.total = total;
this.variance = variance;
}
public long getCount() {
return count;
}
public double getMax() {
return max;
}
public double getMin() {
return min;
}
public double getMean() {
return mean;
}
public double getStdDeviation() {
return stdDeviation;
}
public double getSumOfSquares() {
return sumOfSquares;
}
public double getTotal() {
return total;
}
public double getVariance() {
return variance;
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
/**
* Single term
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
*/
@Deprecated
public class Term {
private String term;
private long count;
public Term(String term, long count) {
this.term = term;
this.count = count;
}
public String getTerm() {
return term;
}
public long getCount() {
return count;
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet.result;
import java.util.List;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult;
import org.springframework.data.elasticsearch.core.facet.FacetType;
/**
* Basic term facet result
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Artur Konczak
* @author Jonathan Yan
* @author Matija Obreza
*/
@Deprecated
public class TermResult extends AbstractFacetResult {
private List<Term> terms;
private long total;
private long other;
private long missing;
public TermResult(String name, List<Term> terms, long total, long other, long missing) {
super(name, FacetType.term);
this.terms = terms;
this.total = total;
this.other = other;
this.missing = missing;
}
public List<Term> getTerms() {
return terms;
}
public long getTotal() {
return total;
}
public long getOther() {
return other;
}
public long getMissing() {
return missing;
}
}

View File

@ -28,6 +28,7 @@ import org.springframework.lang.Nullable;
* @author Sascha Woo
* @author Oliver Gierke
* @author Ivan Greene
* @author Peter-Josef Meisch
*/
public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> {
@ -58,7 +59,7 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
boolean isCreateIndexAndMapping();
/**
* Returns whether the {@link ElasticsearchPersistentEntity} has an score property. If this call returns
* Returns whether the {@link ElasticsearchPersistentEntity} has a score property. If this call returns
* {@literal true}, {@link #getScoreProperty()} will return a non-{@literal null} value.
*
* @return false when {@link ElasticsearchPersistentEntity} does not define a score property.

View File

@ -21,10 +21,10 @@ import org.elasticsearch.index.query.QueryBuilder;
/**
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class AliasBuilder {
private String indexName;
private String aliasName;
private QueryBuilder filterBuilder;
private Map<String, Object> filter;
@ -32,11 +32,6 @@ public class AliasBuilder {
private String indexRouting;
private String routing;
public AliasBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public AliasBuilder withAliasName(String aliasName) {
this.aliasName = aliasName;
return this;
@ -69,7 +64,6 @@ public class AliasBuilder {
public AliasQuery build() {
AliasQuery aliasQuery = new AliasQuery();
aliasQuery.setIndexName(indexName);
aliasQuery.setAliasName(aliasName);
aliasQuery.setFilterBuilder(filterBuilder);
aliasQuery.setFilter(filter);

View File

@ -23,10 +23,10 @@ import org.elasticsearch.index.query.QueryBuilder;
* AliasQuery is useful for creating new alias or deleting existing ones
*
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class AliasQuery {
private String indexName;
private String aliasName;
private QueryBuilder filterBuilder;
private Map<String, Object> filter;
@ -34,14 +34,6 @@ public class AliasQuery {
private String indexRouting;
private String routing;
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getAliasName() {
return aliasName;
}

View File

@ -22,12 +22,11 @@ import org.elasticsearch.index.query.QueryBuilder;
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class DeleteQuery {
private QueryBuilder query;
private String index;
private String type;
private Integer pageSize;
private Long scrollTimeInMillis;
@ -39,22 +38,6 @@ public class DeleteQuery {
this.query = query;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getPageSize() {
return pageSize;
}

View File

@ -28,8 +28,6 @@ public class IndexQuery {
private String id;
private Object object;
private Long version;
private String indexName;
private String type;
private String source;
private String parentId;
@ -57,22 +55,6 @@ public class IndexQuery {
this.version = version;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSource() {
return source;
}

View File

@ -20,14 +20,13 @@ package org.springframework.data.elasticsearch.core.query;
*
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class IndexQueryBuilder {
private String id;
private Object object;
private Long version;
private String indexName;
private String type;
private String source;
private String parentId;
@ -46,16 +45,6 @@ public class IndexQueryBuilder {
return this;
}
public IndexQueryBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public IndexQueryBuilder withType(String type) {
this.type = type;
return this;
}
public IndexQueryBuilder withSource(String source) {
this.source = source;
return this;
@ -69,8 +58,6 @@ public class IndexQueryBuilder {
public IndexQuery build() {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(id);
indexQuery.setIndexName(indexName);
indexQuery.setType(type);
indexQuery.setObject(object);
indexQuery.setParentId(parentId);
indexQuery.setSource(source);

View File

@ -24,7 +24,6 @@ import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* NativeSearchQuery
@ -43,7 +42,6 @@ public class NativeSearchQuery extends AbstractQuery {
private List<SortBuilder> sorts;
private final List<ScriptField> scriptFields = new ArrayList<>();
private CollapseBuilder collapseBuilder;
private List<FacetRequest> facets;
private List<AbstractAggregationBuilder> aggregations;
private HighlightBuilder highlightBuilder;
private HighlightBuilder.Field[] highlightFields;
@ -126,23 +124,6 @@ public class NativeSearchQuery extends AbstractQuery {
this.collapseBuilder = collapseBuilder;
}
public void addFacet(FacetRequest facetRequest) {
if (facets == null) {
facets = new ArrayList<>();
}
facets.add(facetRequest);
}
public void setFacets(List<FacetRequest> facets) {
this.facets = facets;
}
public List<FacetRequest> getFacets() {
return facets;
}
public List<AbstractAggregationBuilder> getAggregations() {
return aggregations;
}

View File

@ -29,7 +29,6 @@ import org.elasticsearch.search.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/**
* NativeSearchQuery
@ -50,7 +49,6 @@ public class NativeSearchQueryBuilder {
private QueryBuilder filterBuilder;
private List<ScriptField> scriptFields = new ArrayList<>();
private List<SortBuilder> sortBuilders = new ArrayList<>();
private List<FacetRequest> facetRequests = new ArrayList<>();
private List<AbstractAggregationBuilder> aggregationBuilders = new ArrayList<>();
private HighlightBuilder highlightBuilder;
private HighlightBuilder.Field[] highlightFields;
@ -99,11 +97,6 @@ public class NativeSearchQueryBuilder {
return this;
}
public NativeSearchQueryBuilder withFacet(FacetRequest facetRequest) {
facetRequests.add(facetRequest);
return this;
}
public NativeSearchQueryBuilder withHighlightBuilder(HighlightBuilder highlightBuilder) {
this.highlightBuilder = highlightBuilder;
return this;
@ -219,10 +212,6 @@ public class NativeSearchQueryBuilder {
nativeSearchQuery.setCollapseBuilder(collapseBuilder);
}
if (!isEmpty(facetRequests)) {
nativeSearchQuery.setFacets(facetRequests);
}
if (!isEmpty(aggregationBuilders)) {
nativeSearchQuery.setAggregations(aggregationBuilders);
}

View File

@ -86,6 +86,7 @@ public interface Query {
*
* @return
*/
@Deprecated
List<String> getIndices();
/**
@ -93,6 +94,7 @@ public interface Query {
*
* @param indices
*/
@Deprecated
void addIndices(String... indices);
/**
@ -100,6 +102,7 @@ public interface Query {
*
* @param types
*/
@Deprecated
void addTypes(String... types);
/**
@ -107,6 +110,7 @@ public interface Query {
*
* @return
*/
@Deprecated
List<String> getTypes();
/**

View File

@ -21,14 +21,12 @@ import org.elasticsearch.action.update.UpdateRequest;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class UpdateQuery {
private String id;
private UpdateRequest updateRequest;
private String indexName;
private String type;
private Class clazz;
private boolean doUpsert;
public String getId() {
@ -47,30 +45,6 @@ public class UpdateQuery {
this.updateRequest = updateRequest;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Class getClazz() {
return clazz;
}
public void setClazz(Class clazz) {
this.clazz = clazz;
}
public boolean DoUpsert() {
return doUpsert;
}

View File

@ -21,15 +21,13 @@ import org.elasticsearch.action.update.UpdateRequest;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Peter-Josef Meisch
*/
public class UpdateQueryBuilder {
private String id;
private UpdateRequest updateRequest;
private IndexRequest indexRequest;
private String indexName;
private String type;
private Class clazz;
private boolean doUpsert;
public UpdateQueryBuilder withId(String id) {
@ -47,21 +45,6 @@ public class UpdateQueryBuilder {
return this;
}
public UpdateQueryBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public UpdateQueryBuilder withType(String type) {
this.type = type;
return this;
}
public UpdateQueryBuilder withClass(Class clazz) {
this.clazz = clazz;
return this;
}
public UpdateQueryBuilder withDoUpsert(boolean doUpsert) {
this.doUpsert = doUpsert;
return this;
@ -70,9 +53,6 @@ public class UpdateQueryBuilder {
public UpdateQuery build() {
UpdateQuery updateQuery = new UpdateQuery();
updateQuery.setId(id);
updateQuery.setIndexName(indexName);
updateQuery.setType(type);
updateQuery.setClazz(clazz);
if (this.indexRequest != null) {
if (this.updateRequest == null) {
updateRequest = new UpdateRequest();

View File

@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.repository.query;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
@ -57,6 +58,8 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
CriteriaQuery query = createQuery(accessor);
Assert.notNull(query, "unsupported query");
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
if (tree.isLimiting()) {
query.setMaxResults(tree.getMaxResults());
@ -64,55 +67,60 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
if (tree.isDelete()) {
Object result = countOrGetDocumentsForDelete(query, accessor);
elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType());
elasticsearchOperations.delete(query, clazz, index);
return result;
} else if (queryMethod.isPageQuery()) {
query.setPageable(accessor.getPageable());
return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForPage(query, clazz, index);
} else if (queryMethod.isStreamQuery()) {
Class<?> entityType = queryMethod.getEntityInformation().getJavaType();
Class<?> entityType = clazz;
if (accessor.getPageable().isUnpaged()) {
query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE));
} else {
query.setPageable(accessor.getPageable());
}
return StreamUtils
.createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType));
.createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType, index));
} else if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isUnpaged()) {
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
int itemCount = (int) elasticsearchOperations.count(query, clazz,
index);
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
} else {
query.setPageable(accessor.getPageable());
}
return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForList(query, clazz, index);
} else if (tree.isCountProjection()) {
return elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.count(query, clazz, index);
}
return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForObject(query, clazz, index);
}
private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) {
Object result = null;
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations
.getIndexCoordinatesFor(clazz);
if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isUnpaged()) {
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
int itemCount = (int) elasticsearchOperations.count(query, clazz,
index);
query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
} else {
query.setPageable(accessor.getPageable());
}
result = elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType());
result = elasticsearchOperations.queryForList(query, clazz, index);
}
if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) {
result = elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType());
result = elasticsearchOperations.count(query, clazz, index);
}
return result;
}

View File

@ -20,6 +20,7 @@ import java.util.regex.Pattern;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.convert.DateTimeConverters;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.repository.query.ParametersParameterAccessor;
@ -68,17 +69,19 @@ public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQue
public Object execute(Object[] parameters) {
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
StringQuery stringQuery = createQuery(accessor);
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
if (queryMethod.isPageQuery()) {
stringQuery.setPageable(accessor.getPageable());
return elasticsearchOperations.queryForPage(stringQuery, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForPage(stringQuery, clazz, index);
} else if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isPaged()) {
stringQuery.setPageable(accessor.getPageable());
}
return elasticsearchOperations.queryForList(stringQuery, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForList(stringQuery, clazz, index);
}
return elasticsearchOperations.queryForObject(stringQuery, queryMethod.getEntityInformation().getJavaType());
return elasticsearchOperations.queryForObject(stringQuery, clazz, index);
}
protected StringQuery createQuery(ParametersParameterAccessor parameterAccessor) {

View File

@ -36,6 +36,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -72,7 +73,6 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
public AbstractElasticsearchRepository() {}
public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) {
Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!");
this.setElasticsearchOperations(elasticsearchOperations);
@ -80,7 +80,6 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
public AbstractElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metadata,
ElasticsearchOperations elasticsearchOperations) {
this(elasticsearchOperations);
Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!");
@ -98,124 +97,99 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
}
private void createIndex() {
elasticsearchOperations.createIndex(getEntityClass());
}
private void putMapping() {
elasticsearchOperations.putMapping(getEntityClass());
}
private boolean createIndexAndMapping() {
return elasticsearchOperations.getPersistentEntityFor(getEntityClass()).isCreateIndexAndMapping();
}
@Override
public Optional<T> findById(ID id) {
GetQuery query = new GetQuery();
query.setId(stringIdRepresentation(id));
return Optional.ofNullable(elasticsearchOperations.queryForObject(query, getEntityClass()));
return Optional.ofNullable(elasticsearchOperations.get(query, getEntityClass(), getIndexCoordinates()));
}
@Override
public Iterable<T> findAll() {
int itemCount = (int) this.count();
if (itemCount == 0) {
return new PageImpl<>(Collections.<T> emptyList());
}
return this.findAll(PageRequest.of(0, Math.max(1, itemCount)));
}
@Override
public Page<T> findAll(Pageable pageable) {
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build();
return elasticsearchOperations.queryForPage(query, getEntityClass());
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
}
@Override
public Iterable<T> findAll(Sort sort) {
int itemCount = (int) this.count();
if (itemCount == 0) {
return new PageImpl<>(Collections.<T> emptyList());
}
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withPageable(PageRequest.of(0, itemCount, sort)).build();
return elasticsearchOperations.queryForPage(query, getEntityClass());
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
}
@Override
public Iterable<T> findAllById(Iterable<ID> ids) {
Assert.notNull(ids, "ids can't be null.");
NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build();
return elasticsearchOperations.multiGet(query, getEntityClass());
return elasticsearchOperations.multiGet(query, getEntityClass(), getIndexCoordinates());
}
@Override
public long count() {
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
return elasticsearchOperations.count(query, getEntityClass());
return elasticsearchOperations.count(query, getEntityClass(), getIndexCoordinates());
}
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity.");
elasticsearchOperations.index(createIndexQuery(entity));
elasticsearchOperations.refresh(entityInformation.getIndexName());
elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates());
elasticsearchOperations.refresh(getIndexCoordinates());
return entity;
}
public <S extends T> List<S> save(List<S> entities) {
Assert.notNull(entities, "Cannot insert 'null' as a List.");
return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList());
}
@Override
public <S extends T> S index(S entity) {
return save(entity);
}
@Override
public <S extends T> S indexWithoutRefresh(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity.");
elasticsearchOperations.index(createIndexQuery(entity));
elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates());
return entity;
}
@Override
public <S extends T> Iterable<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "Cannot insert 'null' as a List.");
List<IndexQuery> queries = Streamable.of(entities).stream().map(this::createIndexQuery)
.collect(Collectors.toList());
if (!queries.isEmpty()) {
elasticsearchOperations.bulkIndex(queries);
elasticsearchOperations.refresh(entityInformation.getIndexName());
elasticsearchOperations.bulkIndex(queries, getIndexCoordinates());
elasticsearchOperations.refresh(getIndexCoordinates());
}
return entities;
@ -223,76 +197,64 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@Override
public boolean existsById(ID id) {
return findById(id).isPresent();
}
@Override
public Iterable<T> search(QueryBuilder query) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build();
int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass());
int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass(), getIndexCoordinates());
if (count == 0) {
return new PageImpl<>(Collections.<T> emptyList());
}
searchQuery.setPageable(PageRequest.of(0, count));
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass());
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates());
}
@Override
public Page<T> search(QueryBuilder query, Pageable pageable) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build();
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass());
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates());
}
@Override
public Page<T> search(NativeSearchQuery query) {
return elasticsearchOperations.queryForPage(query, getEntityClass());
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
}
@Override
public Page<T> searchSimilar(T entity, String[] fields, Pageable pageable) {
Assert.notNull(entity, "Cannot search similar records for 'null'.");
Assert.notNull(pageable, "'pageable' cannot be 'null'");
MoreLikeThisQuery query = new MoreLikeThisQuery();
query.setId(stringIdRepresentation(extractIdFromBean(entity)));
query.setPageable(pageable);
if (fields != null) {
query.addFields(fields);
}
return elasticsearchOperations.moreLikeThis(query, getEntityClass());
return elasticsearchOperations.moreLikeThis(query, getEntityClass(), getIndexCoordinates());
}
@Override
public void deleteById(ID id) {
Assert.notNull(id, "Cannot delete entity with id 'null'.");
elasticsearchOperations.delete(entityInformation.getIndexName(), entityInformation.getType(),
stringIdRepresentation(id));
elasticsearchOperations.refresh(entityInformation.getIndexName());
IndexCoordinates indexCoordinates = getIndexCoordinates();
elasticsearchOperations.delete(stringIdRepresentation(id), indexCoordinates);
elasticsearchOperations.refresh(indexCoordinates);
}
@Override
public void delete(T entity) {
Assert.notNull(entity, "Cannot delete 'null' entity.");
deleteById(extractIdFromBean(entity));
elasticsearchOperations.refresh(entityInformation.getIndexName());
elasticsearchOperations.refresh(getIndexCoordinates());
}
@Override
public void deleteAll(Iterable<? extends T> entities) {
Assert.notNull(entities, "Cannot delete 'null' list.");
for (T entity : entities) {
delete(entity);
@ -301,21 +263,19 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@Override
public void deleteAll() {
DeleteQuery deleteQuery = new DeleteQuery();
deleteQuery.setQuery(matchAllQuery());
elasticsearchOperations.delete(deleteQuery, getEntityClass());
elasticsearchOperations.refresh(entityInformation.getIndexName());
IndexCoordinates indexCoordinates = getIndexCoordinates();
elasticsearchOperations.delete(deleteQuery, indexCoordinates);
elasticsearchOperations.refresh(indexCoordinates);
}
@Override
public void refresh() {
elasticsearchOperations.refresh(getEntityClass());
}
private IndexQuery createIndexQuery(T entity) {
IndexQuery query = new IndexQuery();
query.setObject(entity);
query.setId(stringIdRepresentation(extractIdFromBean(entity)));
@ -326,14 +286,13 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@SuppressWarnings("unchecked")
private Class<T> resolveReturnedClassFromGenericType() {
ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass());
return (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
private ParameterizedType resolveReturnedClassFromGenericType(Class<?> clazz) {
Object genericSuperclass = clazz.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type rawtype = parameterizedType.getRawType();
@ -355,25 +314,20 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
throw new InvalidDataAccessApiUsageException("Unable to resolve EntityClass. Please use according setter!", e);
}
}
return entityClass;
}
private boolean isEntityClassSet() {
return entityClass != null;
}
public final void setEntityClass(Class<T> entityClass) {
Assert.notNull(entityClass, "EntityClass must not be null.");
this.entityClass = entityClass;
}
public final void setElasticsearchOperations(ElasticsearchOperations elasticsearchOperations) {
Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null.");
this.elasticsearchOperations = elasticsearchOperations;
}
@ -382,9 +336,7 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
}
private List<String> stringIdsRepresentation(Iterable<ID> ids) {
Assert.notNull(ids, "ids can't be null.");
List<String> stringIds = new ArrayList<>();
for (ID id : ids) {
stringIds.add(stringIdRepresentation(id));
@ -402,4 +354,8 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
private String extractParentIdFromBean(T entity) {
return entityInformation.getParentId(entity);
}
private IndexCoordinates getIndexCoordinates() {
return elasticsearchOperations.getIndexCoordinatesFor(getEntityClass());
}
}

View File

@ -45,6 +45,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
@ -122,14 +123,15 @@ public class NestedObjectTests {
indexQueries.add(indexQuery1);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Person.class);
QueryBuilder builder = nestedQuery("car",
boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class);
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index);
assertThat(persons).hasSize(1);
}
@ -141,14 +143,15 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson();
// when
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class);
// then
GetQuery getQuery = new GetQuery();
getQuery.setId("1");
PersonMultipleLevelNested personIndexed = elasticsearchTemplate.queryForObject(getQuery,
PersonMultipleLevelNested.class);
PersonMultipleLevelNested personIndexed = elasticsearchTemplate.get(getQuery, PersonMultipleLevelNested.class,
IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
assertThat(personIndexed).isNotNull();
}
@ -159,7 +162,8 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson();
// when
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
// then
Map<String, Object> mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class);
@ -178,7 +182,9 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson();
// when
elasticsearchTemplate.bulkIndex(indexQueries);
IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries,
index);
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class);
// then
@ -189,7 +195,7 @@ public class NestedObjectTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
Page<PersonMultipleLevelNested> personIndexed = elasticsearchTemplate.queryForPage(searchQuery,
PersonMultipleLevelNested.class);
PersonMultipleLevelNested.class, index);
assertThat(personIndexed).isNotNull();
assertThat(personIndexed.getTotalElements()).isEqualTo(1);
assertThat(personIndexed.getContent().get(0).getId()).isEqualTo("1");
@ -317,14 +323,15 @@ public class NestedObjectTests {
indexQueries.add(indexQuery1);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Person.class);
// when
QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class);
List<Person> persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index);
// then
assertThat(persons).hasSize(1);
@ -365,13 +372,14 @@ public class NestedObjectTests {
indexQueries.add(indexQuery2);
// when
elasticsearchTemplate.bulkIndex(indexQueries);
IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes( "book");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Book.class);
// then
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build();
Page<Book> books = elasticsearchTemplate.queryForPage(searchQuery, Book.class);
Page<Book> books = elasticsearchTemplate.queryForPage(searchQuery, Book.class, index);
assertThat(books.getContent()).hasSize(1);
assertThat(books.getContent().get(0).getId()).isEqualTo(book2.getId());

View File

@ -22,16 +22,9 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import lombok.Builder;
import lombok.Data;
import java.io.IOException;
import java.lang.Object;
import java.util.HashMap;
import java.util.Map;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@ -41,7 +34,6 @@ import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.util.ReflectionTestUtils;
/**
* @author Rizwan Idrees
@ -56,7 +48,6 @@ import org.springframework.test.util.ReflectionTestUtils;
* @author Sascha Woo
* @author Don Wellington
* @author Peter-Josef Meisch
* @author Massimiliano Poggi
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
@ -68,65 +59,12 @@ public class ElasticsearchRestTemplateTests extends ElasticsearchTemplateTests {
// when
IndexRequest indexRequest = new IndexRequest();
indexRequest.source("{}", XContentType.JSON);
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class)
.withIndexRequest(indexRequest).build();
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build();
assertThatThrownBy(() -> {
elasticsearchTemplate.update(updateQuery);
elasticsearchTemplate.update(updateQuery, index);
}).isInstanceOf(ElasticsearchStatusException.class);
}
@Test // DATAES-227
@Override
public void shouldUseUpsertOnUpdate() throws IOException {
// given
Map<String, Object> doc = new HashMap<>();
doc.put("id", "1");
doc.put("message", "test");
UpdateRequest updateRequest = new UpdateRequest() //
.doc(doc) //
.upsert(doc);
UpdateQuery updateQuery = new UpdateQueryBuilder() //
.withClass(SampleEntity.class) //
.withId("1") //
.withUpdateRequest(updateRequest).build();
// when
UpdateRequest request = (UpdateRequest) ReflectionTestUtils //
.invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery);
// then
assertThat(request).isNotNull();
assertThat(request.upsertRequest()).isNotNull();
}
@Test // DATAES-693
public void shouldReturnSourceWhenRequested() throws IOException {
// given
Map<String, Object> doc = new HashMap<>();
doc.put("id", "1");
doc.put("message", "test");
UpdateRequest updateRequest = new UpdateRequest()
.doc(doc)
.fetchSource(FetchSourceContext.FETCH_SOURCE);
UpdateQuery updateQuery = new UpdateQueryBuilder() //
.withClass(SampleEntity.class) //
.withId("1") //
.withUpdateRequest(updateRequest).build();
// when
UpdateRequest request = (UpdateRequest) ReflectionTestUtils //
.invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery);
// then
assertThat(request).isNotNull();
assertThat(request.fetchSource()).isEqualTo(FetchSourceContext.FETCH_SOURCE);
}
@Data
@Builder
@Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0,

View File

@ -83,7 +83,7 @@ public class ElasticsearchTemplateParentChildTests {
// find all parents that have the first child
QueryBuilder query = hasChildQuery(ParentEntity.CHILD_TYPE,
QueryBuilders.termQuery("name", child1name.toLowerCase()), ScoreMode.None);
List<ParentEntity> parents = elasticsearchTemplate.queryForList(new NativeSearchQuery(query), ParentEntity.class);
List<ParentEntity> parents = elasticsearchTemplate.queryForList(new NativeSearchQuery(query), ParentEntity.class, IndexCoordinates.of(ParentEntity.INDEX));
// we're expecting only the first parent as result
assertThat(parents).hasSize(1);
@ -105,7 +105,7 @@ public class ElasticsearchTemplateParentChildTests {
XContentBuilder builder;
builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder);
UpdateResponse response = update(updateRequest);
UpdateResponse response = update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
assertThat(response.getShardInfo().getSuccessful()).isEqualTo(1);
}
@ -124,7 +124,7 @@ public class ElasticsearchTemplateParentChildTests {
XContentBuilder builder;
builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder);
update(updateRequest);
update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
}
@Ignore(value = "DATAES-421")
@ -142,7 +142,7 @@ public class ElasticsearchTemplateParentChildTests {
builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder);
updateRequest.doc().routing(parent.getId());
update(updateRequest);
update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
}
private ParentEntity index(String parentId, String name) {
@ -151,7 +151,7 @@ public class ElasticsearchTemplateParentChildTests {
IndexQuery index = new IndexQuery();
index.setId(parent.getId());
index.setObject(parent);
elasticsearchTemplate.index(index);
elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.PARENT_TYPE));
return parent;
}
@ -163,19 +163,17 @@ public class ElasticsearchTemplateParentChildTests {
index.setId(child.getId());
index.setObject(child);
index.setParentId(child.getParentId());
elasticsearchTemplate.index(index);
elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
return child;
}
private UpdateResponse update(UpdateRequest updateRequest) {
private UpdateResponse update(UpdateRequest updateRequest, IndexCoordinates index) {
UpdateQuery update = new UpdateQuery();
update.setId(updateRequest.id());
update.setType(updateRequest.type());
update.setIndexName(updateRequest.index());
update.setUpdateRequest(updateRequest);
return elasticsearchTemplate.update(update);
return elasticsearchTemplate.update(update, index);
}
/**

View File

@ -46,10 +46,9 @@ public class ElasticsearchTransportTemplateTests extends ElasticsearchTemplateTe
// when
IndexRequest indexRequest = new IndexRequest();
indexRequest.source("{}", XContentType.JSON);
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class)
.withIndexRequest(indexRequest).build();
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build();
assertThatThrownBy(() -> {
elasticsearchTemplate.update(updateQuery);
elasticsearchTemplate.update(updateQuery, index);
}).isInstanceOf(DocumentMissingException.class);
}

View File

@ -0,0 +1,54 @@
/*
* 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.core;
import static org.assertj.core.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* @author Peter-Josef Meisch
*/
class IndexCoordinatesTest {
@Test
void cannotBeInitializedWithNullIndexName() {
assertThatThrownBy(() -> {
IndexCoordinates.of(null);
}).isInstanceOf(IllegalArgumentException.class);
}
@Test
void cannotBeInitializedWithNullIndexNames() {
assertThatThrownBy(() -> {
IndexCoordinates.of((String[]) null);
}).isInstanceOf(IllegalArgumentException.class);
}
@Test
void cannotBeInitializedWithEmptyIndexNames() {
assertThatThrownBy(() -> {
IndexCoordinates.of(new String[] {});
}).isInstanceOf(IllegalArgumentException.class);
}
@Test
void shouldHaveEmptyTypesWhenNotSet() {
IndexCoordinates indexCoordinates = IndexCoordinates.of("test");
assertThat(indexCoordinates.getTypeNames()).isEmpty();
}
}

View File

@ -53,6 +53,7 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class LogEntityTests {
private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes( "test-log-type");
@Autowired private ElasticsearchTemplate template;
@BeforeEach
@ -73,7 +74,7 @@ public class LogEntityTests {
IndexQuery indexQuery4 = new LogEntityBuilder("4").action("update").date(dateFormatter.parse("2013-10-19 18:04"))
.code(2).ip("10.10.10.4").buildIndex();
template.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4));
template.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index);
template.refresh(LogEntity.class);
}
@ -82,7 +83,7 @@ public class LogEntityTests {
// when
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build();
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class);
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class, index);
// then
assertThat(entities).isNotNull().hasSize(1);
@ -95,7 +96,7 @@ public class LogEntityTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build();
assertThatThrownBy(() -> {
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class);
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class, index);
}).isInstanceOf(SearchPhaseExecutionException.class);
}
@ -105,7 +106,7 @@ public class LogEntityTests {
// when
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build();
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class);
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class, index);
// then
assertThat(entities).isNotNull().hasSize(3);

View File

@ -61,9 +61,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.util.StringUtils;
/**
@ -76,7 +74,6 @@ import org.springframework.util.StringUtils;
* @author Martin Choraine
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
public class ReactiveElasticsearchTemplateTests {
static final String DEFAULT_INDEX = "reactive-template-test-index";
@ -139,8 +136,9 @@ public class ReactiveElasticsearchTemplateTests {
restTemplate.refresh(SampleEntity.class);
List<SampleEntity> result = restTemplate
.queryForList(new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class);
List<SampleEntity> result = restTemplate.queryForList(
new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class,
IndexCoordinates.of(DEFAULT_INDEX));
assertThat(result).hasSize(1);
}
@ -171,8 +169,8 @@ public class ReactiveElasticsearchTemplateTests {
.expectNextCount(1)//
.verifyComplete();
restTemplate.refresh(DEFAULT_INDEX);
restTemplate.refresh(ALTERNATE_INDEX);
restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX));
restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX));
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse();
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue();
@ -192,8 +190,9 @@ public class ReactiveElasticsearchTemplateTests {
@Test // DATAES-504
public void insertShouldErrorOnNullEntity() {
assertThatThrownBy(() -> template.save(null)).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> {
template.save(null);
}).isInstanceOf(IllegalArgumentException.class);
}
@Test // DATAES-519
@ -245,7 +244,9 @@ public class ReactiveElasticsearchTemplateTests {
@Test // DATAES-504
public void findByIdShouldErrorForNullId() {
assertThatThrownBy(() -> template.findById(null, SampleEntity.class)).isInstanceOf(IllegalArgumentException.class);
assertThatThrownBy(() -> {
template.findById(null, SampleEntity.class);
}).isInstanceOf(IllegalArgumentException.class);
}
@Test // DATAES-504
@ -254,13 +255,12 @@ public class ReactiveElasticsearchTemplateTests {
SampleEntity sampleEntity = randomEntity("some message");
IndexQuery indexQuery = getIndexQuery(sampleEntity);
indexQuery.setIndexName(ALTERNATE_INDEX);
restTemplate.index(indexQuery);
restTemplate.index(indexQuery, IndexCoordinates.of(ALTERNATE_INDEX).withTypes( "test-type"));
restTemplate.refresh(SampleEntity.class);
restTemplate.refresh(DEFAULT_INDEX);
restTemplate.refresh(ALTERNATE_INDEX);
restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX));
restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX));
template.findById(sampleEntity.getId(), SampleEntity.class) //
.as(StepVerifier::create) //
@ -586,8 +586,8 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)//
.verifyComplete();
restTemplate.refresh(thisIndex);
restTemplate.refresh(thatIndex);
restTemplate.refresh(IndexCoordinates.of(thisIndex));
restTemplate.refresh(IndexCoordinates.of(thatIndex));
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "test")) //
@ -616,8 +616,8 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)//
.verifyComplete();
restTemplate.refresh(thisIndex);
restTemplate.refresh(thatIndex);
restTemplate.refresh(IndexCoordinates.of(thisIndex));
restTemplate.refresh(IndexCoordinates.of(thatIndex));
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "negative")) //
@ -725,10 +725,12 @@ public class ReactiveElasticsearchTemplateTests {
private void index(SampleEntity... entities) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes( "test-type");
if (entities.length == 1) {
restTemplate.index(getIndexQuery(entities[0]));
restTemplate.index(getIndexQuery(entities[0]), indexCoordinates);
} else {
restTemplate.bulkIndex(getIndexQueries(entities));
restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates);
}
restTemplate.refresh(SampleEntity.class);

View File

@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
@ -89,10 +90,11 @@ public class ElasticsearchTemplateAggregationTests {
.addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000)
.score(40).buildIndex();
elasticsearchTemplate.index(article1);
elasticsearchTemplate.index(article2);
elasticsearchTemplate.index(article3);
elasticsearchTemplate.index(article4);
IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes( "article");
elasticsearchTemplate.index(article1, index);
elasticsearchTemplate.index(article2, index);
elasticsearchTemplate.index(article3, index);
elasticsearchTemplate.index(article4, index);
elasticsearchTemplate.refresh(ArticleEntity.class);
}
@ -118,7 +120,7 @@ public class ElasticsearchTemplateAggregationTests {
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
}, null, IndexCoordinates.of(INDEX_NAME).withTypes("article"));
// then
assertThat(aggregations).isNotNull();
assertThat(aggregations.asMap().get("subjects")).isNotNull();

View File

@ -32,6 +32,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
@ -66,7 +67,7 @@ public class ElasticsearchTemplateCompletionTests {
indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[] { "Artur", "Konczak" })
.buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type"));
elasticsearchTemplate.refresh(CompletionEntity.class);
}
@ -88,7 +89,8 @@ public class ElasticsearchTemplateCompletionTests {
indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak")
.suggest(new String[] { "Artur", "Konczak" }).buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type"));
elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class);
}
@ -106,7 +108,8 @@ public class ElasticsearchTemplateCompletionTests {
indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4")
.suggest(new String[] { "Mewes Kochheim4" }, Integer.MAX_VALUE).buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type"));
elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class);
}
@ -132,7 +135,8 @@ public class ElasticsearchTemplateCompletionTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), CompletionEntity.class);
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type"));
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -152,7 +156,8 @@ public class ElasticsearchTemplateCompletionTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), CompletionEntity.class);
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type"));
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -173,7 +178,7 @@ public class ElasticsearchTemplateCompletionTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
AnnotatedCompletionEntity.class);
IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type"));
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();

View File

@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.CompletionContext;
import org.springframework.data.elasticsearch.annotations.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
@ -86,7 +87,8 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak")
.suggest(new String[] { "Artur", "Konczak" }, context4).buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
elasticsearchTemplate.refresh(ContextCompletionEntity.class);
}
@ -123,7 +125,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class);
IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -155,7 +157,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class);
IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -187,7 +189,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when
SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class);
IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();

View File

@ -1,695 +0,0 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.core.facet;
import static org.assertj.core.api.Assertions.*;
import static org.elasticsearch.index.query.QueryBuilders.*;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.FacetedPage;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.facet.request.HistogramFacetRequestBuilder;
import org.springframework.data.elasticsearch.core.facet.request.NativeFacetRequest;
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequestBuilder;
import org.springframework.data.elasticsearch.core.facet.request.StatisticalFacetRequestBuilder;
import org.springframework.data.elasticsearch.core.facet.request.TermFacetRequestBuilder;
import org.springframework.data.elasticsearch.core.facet.result.HistogramResult;
import org.springframework.data.elasticsearch.core.facet.result.IntervalUnit;
import org.springframework.data.elasticsearch.core.facet.result.Range;
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
import org.springframework.data.elasticsearch.core.facet.result.StatisticalResult;
import org.springframework.data.elasticsearch.core.facet.result.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexInitializer;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Jonathan Yan
* @author Artur Konczak
* @author Peter-Josef Meisch
*/
@SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class ElasticsearchTemplateFacetTests {
private static final String RIZWAN_IDREES = "Rizwan Idrees";
private static final String MOHSIN_HUSEN = "Mohsin Husen";
private static final String JONATHAN_YAN = "Jonathan Yan";
private static final String ARTUR_KONCZAK = "Artur Konczak";
private static final int YEAR_2002 = 2002;
private static final int YEAR_2001 = 2001;
private static final int YEAR_2000 = 2000;
private static final String PUBLISHED_YEARS = "publishedYears";
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
@BeforeEach
public void before() {
IndexInitializer.init(elasticsearchTemplate, ArticleEntity.class);
IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").addAuthor(RIZWAN_IDREES)
.addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10).buildIndex();
IndexQuery article2 = new ArticleEntityBuilder("2").title("article three").addAuthor(RIZWAN_IDREES)
.addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addPublishedYear(YEAR_2000).score(20).buildIndex();
IndexQuery article3 = new ArticleEntityBuilder("3").title("article two").addAuthor(RIZWAN_IDREES)
.addAuthor(ARTUR_KONCZAK).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(30).buildIndex();
IndexQuery article4 = new ArticleEntityBuilder("4").title("article one").addAuthor(RIZWAN_IDREES)
.addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(40).buildIndex();
elasticsearchTemplate.index(article1);
elasticsearchTemplate.index(article2);
elasticsearchTemplate.index(article3);
elasticsearchTemplate.index(article4);
elasticsearchTemplate.refresh(ArticleEntity.class);
}
@Test
public void shouldReturnFacetedAuthorsForGivenQueryWithDefaultOrder() {
// given
String facetName = "fauthors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES);
assertThat(term.getCount()).isEqualTo(4);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(term.getCount()).isEqualTo(2);
term = facet.getTerms().get(3);
assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN);
assertThat(term.getCount()).isEqualTo(1);
assertThat(facet.getTotal()).isEqualTo(4);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnFacetedAuthorsForGivenFilteredQuery() {
// given
String facetName = "fauthors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES);
assertThat(term.getCount()).isEqualTo(4);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(term.getCount()).isEqualTo(2);
assertThat(facet.getTotal()).isEqualTo(4);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldExcludeTermsFromFacetedAuthorsForGivenQuery() {
// given
String facetName = "fauthors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched")
.excludeTerms(RIZWAN_IDREES, ARTUR_KONCZAK).build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
assertThat(facet.getTerms()).hasSize(2);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(term.getCount()).isEqualTo(2);
Term term1 = facet.getTerms().get(1);
assertThat(term1.getTerm()).isEqualTo(JONATHAN_YAN);
assertThat(term1.getCount()).isEqualTo(1);
assertThat(facet.getTotal()).isEqualTo(2);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnFacetedAuthorsForGivenQueryOrderedByTerm() {
// given
String facetName = "fauthors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascTerm().build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN);
assertThat(term.getCount()).isEqualTo(1);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(term.getCount()).isEqualTo(2);
term = facet.getTerms().get(3);
assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES);
assertThat(term.getCount()).isEqualTo(4);
assertThat(facet.getTotal()).isEqualTo(4);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnFacetedAuthorsForGivenQueryOrderedByCountAsc() {
// given
String facetName = "fauthors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascCount().build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN);
assertThat(term.getCount()).isEqualTo(1);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(term.getCount()).isEqualTo(2);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(3);
assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES);
assertThat(term.getCount()).isEqualTo(4);
assertThat(facet.getTotal()).isEqualTo(4);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnFacetedYearsForGivenQuery() {
// given
String facetName = "fyears";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(facetName).fields("publishedYears").descCount().build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
assertThat(facet.getTerms()).hasSize(3);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2000));
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2001));
assertThat(term.getCount()).isEqualTo(2);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2002));
assertThat(term.getCount()).isEqualTo(1);
assertThat(facet.getTotal()).isEqualTo(3);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnExistingFacetedYearsForGivenQuery() {
// given
String facetName = "fyears";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(
new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("publishedYears").descCount().build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
assertThat(facet.getTerms()).hasSize(3);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2000));
assertThat(term.getCount()).isEqualTo(3);
term = facet.getTerms().get(1);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2001));
assertThat(term.getCount()).isEqualTo(2);
term = facet.getTerms().get(2);
assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2002));
assertThat(term.getCount()).isEqualTo(1);
assertThat(facet.getTotal()).isEqualTo(3);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldThrowExeptionsForMultiFieldFacet() {
// given
String facetName = "fyears";
assertThatThrownBy(() -> {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(
new TermFacetRequestBuilder(facetName).fields("publishedYears", "authors.untouched").ascTerm().build())
.build();
}).isInstanceOf(IllegalArgumentException.class);
}
@Test
public void shouldReturnFacetedYearsAndFacetedAuthorsForGivenQuery() {
// given
String numberFacetName = "fAuthors";
String stringFacetName = "fyears";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new TermFacetRequestBuilder(numberFacetName).fields("publishedYears").ascTerm().build())
.withFacet(new TermFacetRequestBuilder(stringFacetName).fields("authors.untouched").ascTerm().build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult numberFacet = (TermResult) result.getFacet(numberFacetName);
assertThat(numberFacet.getTerms()).hasSize(3);
Term numberTerm = numberFacet.getTerms().get(0);
assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2000));
assertThat(numberTerm.getCount()).isEqualTo(3);
numberTerm = numberFacet.getTerms().get(1);
assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2001));
assertThat(numberTerm.getCount()).isEqualTo(2);
numberTerm = numberFacet.getTerms().get(2);
assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2002));
assertThat(numberTerm.getCount()).isEqualTo(1);
TermResult stringFacet = (TermResult) result.getFacet(stringFacetName);
Term stringTerm = stringFacet.getTerms().get(0);
assertThat(stringTerm.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(stringTerm.getCount()).isEqualTo(3);
stringTerm = stringFacet.getTerms().get(1);
assertThat(stringTerm.getTerm()).isEqualTo(JONATHAN_YAN);
assertThat(stringTerm.getCount()).isEqualTo(1);
stringTerm = stringFacet.getTerms().get(2);
assertThat(stringTerm.getTerm()).isEqualTo(MOHSIN_HUSEN);
assertThat(stringTerm.getCount()).isEqualTo(2);
stringTerm = stringFacet.getTerms().get(3);
assertThat(stringTerm.getTerm()).isEqualTo(RIZWAN_IDREES);
assertThat(stringTerm.getCount()).isEqualTo(4);
assertThat(stringFacet.getTotal()).isEqualTo(4);
assertThat(stringFacet.getOther()).isEqualTo(0);
assertThat(stringFacet.getMissing()).isEqualTo(0);
}
@Test
public void shouldThrowExceptionForNativeFacets() {
// given
String facetName = "fyears";
assertThatThrownBy(() -> {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new NativeFacetRequest()).build();
}).isInstanceOf(UnsupportedOperationException.class);
}
@Test
public void shouldFilterResultByRegexForGivenQuery() {
// given
String facetName = "regex_authors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFacet(
new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").regex("Art.*").build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
assertThat(facet.getTerms()).hasSize(1);
Term term = facet.getTerms().get(0);
assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK);
assertThat(term.getCount()).isEqualTo(3);
assertThat(facet.getTotal()).isEqualTo(1);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnAllTermsForGivenQuery() {
// given
String facetName = "all_authors";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(
new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").allTerms().build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
TermResult facet = (TermResult) result.getFacet(facetName);
assertThat(facet.getTerms()).hasSize(4);
assertThat(facet.getTotal()).isEqualTo(4);
assertThat(facet.getOther()).isEqualTo(0);
assertThat(facet.getMissing()).isEqualTo(0);
}
@Test
public void shouldReturnRangeFacetForGivenQuery() {
// given
String facetName = "rangeYears";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new RangeFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).to(YEAR_2000)
.range(YEAR_2000, YEAR_2002).from(YEAR_2002).build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
RangeResult facet = (RangeResult) result.getFacet(facetName);
assertThat(facet.getRanges()).hasSize(3);
Range range = facet.getRanges().get(0);
assertThat(range.getFrom()).isEqualTo(Double.NEGATIVE_INFINITY);
assertThat(range.getTo()).isEqualTo((double) YEAR_2000);
assertThat(range.getCount()).isEqualTo(0);
assertThat(range.getTotal()).isEqualTo(0.0);
range = facet.getRanges().get(1);
assertThat(range.getFrom()).isEqualTo((double) YEAR_2000);
assertThat(range.getTo()).isEqualTo((double) YEAR_2002);
assertThat(range.getCount()).isEqualTo(3);
assertThat(range.getTotal()).isEqualTo(12004.0);
range = facet.getRanges().get(2);
assertThat(range.getFrom()).isEqualTo((double) YEAR_2002);
assertThat(range.getTo()).isEqualTo(Double.POSITIVE_INFINITY);
assertThat(range.getCount()).isEqualTo(1);
assertThat(range.getTotal()).isEqualTo(6003.0);
}
@Test
public void shouldReturnKeyValueRangeFacetForStringValuesInGivenQuery() {
// given
String facetName = "rangeScoreOverYears";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score").to(YEAR_2000)
.range(YEAR_2000, YEAR_2002).from(YEAR_2002).build())
.build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
RangeResult facet = (RangeResult) result.getFacet(facetName);
assertThat(facet.getRanges()).hasSize(3);
Range range = facet.getRanges().get(0);
assertThat(range.getFrom()).isEqualTo(Double.NEGATIVE_INFINITY);
assertThat(range.getTo()).isEqualTo((double) YEAR_2000);
assertThat(range.getCount()).isEqualTo(0);
assertThat(range.getTotal()).isEqualTo(0.0);
range = facet.getRanges().get(1);
assertThat(range.getFrom()).isEqualTo((double) YEAR_2000);
assertThat(range.getTo()).isEqualTo((double) YEAR_2002);
assertThat(range.getCount()).isEqualTo(3);
assertThat(range.getTotal()).isEqualTo(90.0);
range = facet.getRanges().get(2);
assertThat(range.getFrom()).isEqualTo((double) YEAR_2002);
assertThat(range.getTo()).isEqualTo(Double.POSITIVE_INFINITY);
assertThat(range.getCount()).isEqualTo(1);
assertThat(range.getTotal()).isEqualTo(40.0);
}
@Test
public void shouldReturnStatisticalFacetForGivenQuery() {
// given
String facetName = "statPublishedYear";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new StatisticalFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
StatisticalResult facet = (StatisticalResult) result.getFacet(facetName);
assertThat(facet.getCount()).isEqualTo(6);
assertThat(facet.getMax()).isEqualTo(2002.0);
assertThat(facet.getMin()).isEqualTo(2000.0);
}
@Test
public void shouldReturnHistogramFacetForGivenQuery() {
// given
String facetName = "numberPublicationPerYear";
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withFacet(new HistogramFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).interval(1).build()).build();
// when
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
// then
assertThat(result.getNumberOfElements()).isEqualTo(4);
HistogramResult facet = (HistogramResult) result.getFacet(facetName);
assertThat(facet.getIntervalUnit()).hasSize(3);
IntervalUnit unit = facet.getIntervalUnit().get(0);
assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2000));
assertThat(unit.getCount()).isEqualTo(3);
unit = facet.getIntervalUnit().get(1);
assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2001));
assertThat(unit.getCount()).isEqualTo(2);
unit = facet.getIntervalUnit().get(2);
assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2002));
assertThat(unit.getCount()).isEqualTo(1);
}
@Test
public void shouldNotThrowExceptionForNoFacets() {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
AggregatedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
assertThat(result.hasFacets()).isEqualTo(false);
}
/**
* Simple type to test facets
*
* @author Artur Konczak
* @author Mohsin Husen
*/
@Data
@Document(indexName = "test-index-articles-core-facet", type = "article", shards = 1, replicas = 0,
refreshInterval = "-1")
static class ArticleEntity {
@Id private String id;
private String title;
@Field(type = FieldType.Text, fielddata = true) private String subject;
@MultiField(mainField = @Field(type = FieldType.Text),
otherFields = {
@InnerField(suffix = "untouched", type = FieldType.Text, store = true, fielddata = true,
analyzer = "keyword"),
@InnerField(suffix = "sort", type = FieldType.Text, store = true,
analyzer = "keyword") }) private List<String> authors = new ArrayList<>();
@Field(type = FieldType.Integer, store = true) private List<Integer> publishedYears = new ArrayList<>();
private int score;
private ArticleEntity() {
}
public ArticleEntity(String id) {
this.id = id;
}
}
/**
* Simple type to test facets
*
* @author Artur Konczak
* @author Mohsin Husen
*/
static class ArticleEntityBuilder {
private ArticleEntity result;
public ArticleEntityBuilder(String id) {
result = new ArticleEntity(id);
}
public ArticleEntityBuilder title(String title) {
result.setTitle(title);
return this;
}
public ArticleEntityBuilder subject(String subject) {
result.setSubject(subject);
return this;
}
public ArticleEntityBuilder addAuthor(String author) {
result.getAuthors().add(author);
return this;
}
public ArticleEntityBuilder addPublishedYear(Integer year) {
result.getPublishedYears().add(year);
return this;
}
public ArticleEntityBuilder score(int score) {
result.setScore(score);
return this;
}
public ArticleEntity build() {
return result;
}
public IndexQuery buildIndex() {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(result.getId());
indexQuery.setObject(result);
return indexQuery;
}
}
}

View File

@ -36,6 +36,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -61,6 +62,11 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class ElasticsearchTemplateGeoTests {
private final IndexCoordinates locationMarkerIndex = IndexCoordinates.of("test-index-location-marker-core-geo")
.withTypes("geo-annotation-point-type");
private final IndexCoordinates authorMarkerIndex = IndexCoordinates.of("test-index-author-marker-core-geo")
.withTypes("geo-class-point-type");
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
@BeforeEach
@ -77,7 +83,7 @@ public class ElasticsearchTemplateGeoTests {
.add(new AuthorMarkerEntityBuilder("1").name("Franck Marchand").location(45.7806d, 3.0875d).buildIndex());
indexQueries.add(new AuthorMarkerEntityBuilder("2").name("Mohsin Husen").location(51.5171d, 0.1062d).buildIndex());
indexQueries.add(new AuthorMarkerEntityBuilder("3").name("Rizwan Idrees").location(51.5171d, 0.1062d).buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, authorMarkerIndex);
elasticsearchTemplate.refresh(AuthorMarkerEntity.class);
}
@ -109,7 +115,7 @@ public class ElasticsearchTemplateGeoTests {
indexQueries.add(buildIndex(location2));
indexQueries.add(buildIndex(location3));
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, locationMarkerIndex);
elasticsearchTemplate.refresh(LocationMarkerEntity.class);
}
@ -134,7 +140,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(1);
@ -151,7 +157,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria2 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery2,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria2).hasSize(1);
@ -167,7 +173,7 @@ public class ElasticsearchTemplateGeoTests {
new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km"));
// when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(1);
@ -183,7 +189,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -198,7 +204,7 @@ public class ElasticsearchTemplateGeoTests {
new Criteria("locationAsArray").within("51.001000, 0.10100", "1km"));
// when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -213,7 +219,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -229,7 +235,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(queryBuilder.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -245,7 +251,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -263,7 +269,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -281,7 +287,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -299,7 +305,7 @@ public class ElasticsearchTemplateGeoTests {
// when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class);
AuthorMarkerEntity.class, authorMarkerIndex);
// then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -327,17 +333,17 @@ public class ElasticsearchTemplateGeoTests {
// when
List<LocationMarkerEntity> result1 = elasticsearchTemplate.queryForList(location1.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result2 = elasticsearchTemplate.queryForList(location2.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result3 = elasticsearchTemplate.queryForList(location3.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result4 = elasticsearchTemplate.queryForList(location4.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result5 = elasticsearchTemplate.queryForList(location5.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result11 = elasticsearchTemplate.queryForList(location11.build(),
LocationMarkerEntity.class);
LocationMarkerEntity.class, locationMarkerIndex);
// then
assertThat(result1).hasSize(3);

View File

@ -51,6 +51,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.completion.Completion;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -139,12 +140,16 @@ public class MappingBuilderTests extends MappingContextBaseTests {
double price = 2.34;
String id = "abc";
elasticsearchTemplate
.index(buildIndex(StockPrice.builder().id(id).symbol(symbol).price(BigDecimal.valueOf(price)).build()));
IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes( "price");
elasticsearchTemplate.index(buildIndex(StockPrice.builder() //
.id(id) //
.symbol(symbol) //
.price(BigDecimal.valueOf(price)) //
.build()), index);
elasticsearchTemplate.refresh(StockPrice.class);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
List<StockPrice> result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class);
List<StockPrice> result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class, index);
// Then
assertThat(result).hasSize(1);
@ -186,12 +191,14 @@ public class MappingBuilderTests extends MappingContextBaseTests {
Date createdDate = new Date();
String message = "msg";
String id = "abc";
elasticsearchTemplate
.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex());
IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes( "mapping");
elasticsearchTemplate.index(
new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(),
index);
elasticsearchTemplate.refresh(SampleInheritedEntity.class);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
List<SampleInheritedEntity> result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class);
List<SampleInheritedEntity> result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class, index);
// then
assertThat(result).hasSize(1);

View File

@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
@ -54,6 +55,7 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class CriteriaQueryTests {
private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes( "test-type");
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
@BeforeEach
@ -78,13 +80,13 @@ public class CriteriaQueryTests {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(documentId);
indexQuery.setObject(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.index(indexQuery, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("test").and("message").contains("some"));
// when
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(sampleEntity1).isNotNull();
@ -121,13 +123,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("some").or("message").contains("test"));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -152,13 +154,13 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some")));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -184,12 +186,12 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some")));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -213,12 +215,12 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message"));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -255,12 +257,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message"));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -297,13 +299,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
Criteria criteria = new Criteria("message").endsWith("end");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -339,13 +341,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
Criteria criteria = new Criteria("message").startsWith("start");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -381,12 +383,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains"));
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -422,12 +424,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test"));
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -463,13 +465,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search"));
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -505,12 +507,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not());
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(criteriaQuery.getCriteria().isNegating()).isTrue();
@ -549,12 +551,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150));
// when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(sampleEntity).isNotNull();
@ -591,12 +593,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -634,12 +636,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -677,12 +679,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -720,12 +722,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page).isNotNull();
@ -763,12 +765,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1));
// when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1);
@ -784,14 +786,14 @@ public class CriteriaQueryTests {
indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build()));
indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build()));
elasticsearchTemplate.bulkIndex(indexQueries);
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class);
// when
CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("a").or(new Criteria("message").contains("b")));
criteriaQuery.setMinScore(2.0F);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then
assertThat(page.getTotalElements()).isEqualTo(1);
@ -811,13 +813,13 @@ public class CriteriaQueryTests {
IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(documentId);
indexQuery.setObject(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.index(indexQuery, index);
elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!"));
// when
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class);
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then
assertThat(sampleEntity1).isNotNull();

View File

@ -32,6 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
@ -107,9 +108,11 @@ public class DynamicSettingAndMappingEntityRepositoryTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build();
long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class);
IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping").withTypes( "test-setting-type");
long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class,
index);
List<DynamicSettingAndMappingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery,
DynamicSettingAndMappingEntity.class);
DynamicSettingAndMappingEntity.class, index);
// then
assertThat(count).isEqualTo(1L);

View File

@ -26,6 +26,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
@ -70,7 +71,7 @@ public class SpELEntityTests {
// then
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
nativeSearchQuery.addIndices("test-index-abz-entity");
long count = template.count(nativeSearchQuery);
long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity"));
assertThat(count).isEqualTo(2);
}
@ -87,7 +88,7 @@ public class SpELEntityTests {
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
nativeSearchQuery.addIndices("test-index-abz-entity");
nativeSearchQuery.addTypes("myType");
long count = template.count(nativeSearchQuery);
long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity"));
assertThat(count).isEqualTo(1);
}

View File

@ -22,21 +22,24 @@ import lombok.Data;
import java.util.List;
import org.elasticsearch.index.query.QueryBuilders;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.data.elasticsearch.utils.IndexInitializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* SynonymRepositoryTests
@ -44,15 +47,21 @@ import org.springframework.test.context.junit4.SpringRunner;
* @author Artur Konczak
* @author Peter-Josef Meisch
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:synonym-test.xml")
@SpringIntegrationTest
@ContextConfiguration(classes = { SynonymRepositoryTests.Config.class })
public class SynonymRepositoryTests {
@Configuration
@Import({ ElasticsearchTemplateConfiguration.class })
@EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.synonym" },
considerNestedRepositories = true)
static class Config {}
@Autowired private SynonymRepository repository;
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
@Before
@BeforeEach
public void before() {
IndexInitializer.init(elasticsearchTemplate, SynonymEntity.class);
}
@ -76,7 +85,7 @@ public class SynonymRepositoryTests {
List<SynonymEntity> synonymEntities = elasticsearchTemplate.queryForList(
new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("text", "british")).build(),
SynonymEntity.class);
SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes( "synonym-type"));
assertThat(synonymEntities).hasSize(1);
}