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; 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.Logger;
import org.slf4j.LoggerFactory; 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.ElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Mapping; 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.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; 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.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.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; import org.springframework.util.StringUtils;
/** /**
@ -16,11 +46,22 @@ import org.springframework.util.StringUtils;
* @author Sascha Woo * @author Sascha Woo
* @author Peter-Josef Meisch * @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); private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
protected ElasticsearchConverter elasticsearchConverter; 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() { protected ElasticsearchConverter createElasticsearchConverter() {
MappingElasticsearchConverter mappingElasticsearchConverter = new MappingElasticsearchConverter( MappingElasticsearchConverter mappingElasticsearchConverter = new MappingElasticsearchConverter(
@ -29,6 +70,13 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
return mappingElasticsearchConverter; return mappingElasticsearchConverter;
} }
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
if (elasticsearchConverter instanceof ApplicationContextAware) {
((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context);
}
}
protected String buildMapping(Class<?> clazz) { protected String buildMapping(Class<?> clazz) {
// load mapping specified in Mapping annotation if present // 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 @Override
public ElasticsearchConverter getElasticsearchConverter() { public ElasticsearchConverter getElasticsearchConverter() {
return elasticsearchConverter; 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.action.update.UpdateResponse;
import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.springframework.data.domain.Page; 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.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; 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.data.util.CloseableIterator;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
@ -44,28 +52,22 @@ public interface ElasticsearchOperations {
* adding new alias * adding new alias
* *
* @param query * @param query
* @param index
* @return * @return
*/ */
boolean addAlias(AliasQuery query); boolean addAlias(AliasQuery query, IndexCoordinates index);
/** /**
* removing previously created alias * removing previously created alias
* *
* @param query * @param query
* @param index
* @return * @return
*/ */
boolean removeAlias(AliasQuery query); boolean removeAlias(AliasQuery query, IndexCoordinates index);
/** /**
* Create an index for a class * Create an index for given indexName if it does not already exist
*
* @param clazz
* @param <T>
*/
<T> boolean createIndex(Class<T> clazz);
/**
* Create an index for given indexName
* *
* @param indexName * @param indexName
*/ */
@ -79,6 +81,14 @@ public interface ElasticsearchOperations {
*/ */
boolean createIndex(String indexName, Object settings); 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 * Create an index for given class and Settings
* *
@ -96,23 +106,21 @@ public interface ElasticsearchOperations {
<T> boolean putMapping(Class<T> clazz); <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 index
* @param type
* @param clazz * @param clazz
* @since 3.2 * @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 * Create mapping for a given index
* * @param index
* @param indexName
* @param type
* @param mappings * @param mappings
* @param index
*/ */
boolean putMapping(String indexName, String type, Object mappings); boolean putMapping(IndexCoordinates index, Object mappings);
/** /**
* Create mapping for a class * Create mapping for a class
@ -126,17 +134,17 @@ public interface ElasticsearchOperations {
* Get mapping for a class * Get mapping for a class
* *
* @param clazz * @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 index
* @param type
*/ */
Map<String, Object> getMapping(String indexName, String type); Map<String, Object> getMapping(IndexCoordinates index);
/** /**
* Get settings for a given indexName * Get settings for a given indexName
@ -160,34 +168,30 @@ public interface ElasticsearchOperations {
*/ */
List<AliasMetaData> queryForAlias(String indexName); 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 * Execute the query against elasticsearch and return the first returned object
* *
* @param query * @param query
* @param clazz * @param clazz
* @param index
* @return the first matching object * @return the first matching object
*/ */
<T> T queryForObject(GetQuery 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 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);
/** /**
* Execute the query against elasticsearch and return result as {@link Page} * Execute the query against elasticsearch and return result as {@link Page}
@ -196,46 +200,30 @@ public interface ElasticsearchOperations {
* @param clazz * @param clazz
* @return * @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} * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page}
* *
* @param queries * @param queries
* @param clazz * @param clazz
* @param index
* @return * @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} * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page}
* *
* @param queries * @param queries
* @param classes * @param classes
* @param index
* @return * @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} * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}.
*
* @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}.
* <p> * <p>
* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of
* error. * error.
@ -243,65 +231,34 @@ public interface ElasticsearchOperations {
* @param <T> element return type * @param <T> element return type
* @param query * @param query
* @param clazz * @param clazz
* @param index
* @return * @return
* @since 1.3 * @since 1.3
*/ */
<T> CloseableIterator<T> stream(CriteriaQuery query, Class<T> clazz); <T> CloseableIterator<T> stream(Query query, Class<T> clazz, IndexCoordinates index);
/**
* 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);
/** /**
* Execute the criteria query against elasticsearch and return result as {@link List} * Execute the criteria query against elasticsearch and return result as {@link List}
* *
* @param query * @param query
* @param clazz * @param clazz
* @param index
* @param <T> * @param <T>
* @return * @return
*/ */
<T> List<T> queryForList(CriteriaQuery query, Class<T> clazz); <T> List<T> queryForList(Query query, Class<T> clazz, IndexCoordinates index);
/**
* 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);
/** /**
* Execute the multi search query against elasticsearch and return result as {@link List} * Execute the multi search query against elasticsearch and return result as {@link List}
* *
* @param <T>
* @param queries * @param queries
* @param clazz * @param clazz
* @param <T> * @param index
* @return * @return
*/ */
default <T> List<List<T>> queryForList(List<NativeSearchQuery> queries, Class<T> clazz) { default <T> List<List<T>> queryForList(List<Query> queries, Class<T> clazz, IndexCoordinates index) {
return queryForPage(queries, clazz).stream().map(Page::getContent).collect(Collectors.toList()); return queryForPage(queries, clazz, index).stream().map(Page::getContent).collect(Collectors.toList());
} }
/** /**
@ -309,62 +266,53 @@ public interface ElasticsearchOperations {
* *
* @param queries * @param queries
* @param classes * @param classes
* @param index
* @return * @return
*/ */
default List<List<?>> queryForList(List<NativeSearchQuery> queries, List<Class<?>> classes) { default List<List<?>> queryForList(List<Query> queries, List<Class<?>> classes, IndexCoordinates index) {
return queryForPage(queries, classes).stream().map(Page::getContent).collect(Collectors.toList()); return queryForPage(queries, classes, index).stream().map(Page::getContent).collect(Collectors.toList());
} }
/** /**
* Execute the query against elasticsearch and return ids * Execute the query against elasticsearch and return ids
* *
* @param query * @param query
* @return
*/
<T> List<String> queryForIds(NativeSearchQuery query);
/**
* return number of elements found by given query
*
* @param query
* @param clazz * @param clazz
* @param index
* @return * @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 * return number of elements found by given query
* *
* @param query * @param query the query to execute
* @return * @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 * return number of elements found by given query
* *
* @param query * @param query the query to execute
* @param clazz * @param clazz the entity clazz used for property mapping
* @return * @param index the index to run the query against
* @return count
*/ */
<T> long count(NativeSearchQuery query, Class<T> clazz); long count(Query query, @Nullable Class<?> clazz, IndexCoordinates index);
/**
* return number of elements found by given query
*
* @param query
* @return
*/
<T> long count(NativeSearchQuery query);
/** /**
* Execute a multiGet against elasticsearch for the given ids * Execute a multiGet against elasticsearch for the given ids
* *
* @param searchQuery * @param query
* @param clazz * @param clazz
* @param index
* @return * @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 * Index an object. Will do save or update
@ -372,7 +320,7 @@ public interface ElasticsearchOperations {
* @param query * @param query
* @return returns the document id * @return returns the document id
*/ */
String index(IndexQuery query); String index(IndexQuery query, IndexCoordinates index);
/** /**
* Partial update of the document * Partial update of the document
@ -380,15 +328,15 @@ public interface ElasticsearchOperations {
* @param updateQuery * @param updateQuery
* @return * @return
*/ */
UpdateResponse update(UpdateQuery updateQuery); UpdateResponse update(UpdateQuery updateQuery, IndexCoordinates index);
/** /**
* Bulk index all objects. Will do save or update. * Bulk index all objects. Will do save or update.
* *
* @param queries the queries to execute in bulk * @param queries the queries to execute in bulk
*/ */
default void bulkIndex(List<IndexQuery> queries) { default void bulkIndex(List<IndexQuery> queries, IndexCoordinates index) {
bulkIndex(queries, BulkOptions.defaultOptions()); bulkIndex(queries, BulkOptions.defaultOptions(), index);
} }
/** /**
@ -398,15 +346,15 @@ public interface ElasticsearchOperations {
* @param bulkOptions options to be added to the bulk request * @param bulkOptions options to be added to the bulk request
* @since 3.2 * @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 * Bulk update all objects. Will do update
* *
* @param queries the queries to execute in bulk * @param queries the queries to execute in bulk
*/ */
default void bulkUpdate(List<UpdateQuery> queries) { default void bulkUpdate(List<UpdateQuery> queries, IndexCoordinates index) {
bulkUpdate(queries, BulkOptions.defaultOptions()); bulkUpdate(queries, BulkOptions.defaultOptions(), index);
} }
/** /**
@ -416,58 +364,43 @@ public interface ElasticsearchOperations {
* @param bulkOptions options to be added to the bulk request * @param bulkOptions options to be added to the bulk request
* @since 3.2 * @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 id the document ot delete
* @param type * @param index the index from which to delete
* @param id
* @return documentId of the document deleted * @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 * 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 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 * Delete all records matching the query
* *
* @param 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 * Deletes an index for given entity
* *
* @param clazz * @param clazz
* @param <T>
* @return * @return
*/ */
<T> boolean deleteIndex(Class<T> clazz); default boolean deleteIndex(Class<?> clazz) {
return deleteIndex(getPersistentEntityFor(clazz).getIndexName());
}
/** /**
* Deletes an index for given indexName * Deletes an index for given indexName
@ -481,10 +414,11 @@ public interface ElasticsearchOperations {
* check if index is exists * check if index is exists
* *
* @param clazz * @param clazz
* @param <T>
* @return * @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 * check if index is exists for given IndexName
@ -495,49 +429,32 @@ public interface ElasticsearchOperations {
boolean indexExists(String indexName); boolean indexExists(String indexName);
/** /**
* check if type is exists in an index * refresh the index(es)
* *
* @param index * @param index
* @param type
* @return
*/ */
boolean typeExists(String index, String type); void refresh(IndexCoordinates index);
/**
* refresh the index
*
* @param indexName
*/
void refresh(String indexName);
/** /**
* refresh the index * refresh the index
* *
* @param clazz * @param clazz
*/ */
<T> void refresh(Class<T> clazz); default <T> void refresh(Class<T> clazz) {
refresh(getIndexCoordinatesFor(clazz));
}
/** /**
* Returns scrolled page for given query * 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 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 clazz The class of entity to retrieve.
* @param index
* @return The scan id for input query. * @return The scan id for input query.
*/ */
<T> ScrolledPage<T> startScroll(long scrollTimeInMillis, NativeSearchQuery query, Class<T> clazz); <T> ScrolledPage<T> startScroll(long scrollTimeInMillis, Query query, Class<T> clazz, IndexCoordinates index);
/**
* 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> continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz); <T> ScrolledPage<T> continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz);
@ -546,17 +463,18 @@ public interface ElasticsearchOperations {
* *
* @param scrollId * @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. * more like this query to search for documents that are "like" a specific document.
* *
* @param query * @param query
* @param clazz * @param clazz
* @param index
* @param <T> * @param <T>
* @return * @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); ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz);
@ -564,4 +482,20 @@ public interface ElasticsearchOperations {
* @return Converter in use * @return Converter in use
*/ */
ElasticsearchConverter getElasticsearchConverter(); 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; package org.springframework.data.elasticsearch.core;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -38,13 +37,18 @@ import org.springframework.util.StringUtils;
* *
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
@RequiredArgsConstructor
class EntityOperations { class EntityOperations {
private static final String ID_FIELD = "id"; 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; private final @NonNull MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> context;
/** /**
@ -116,7 +120,7 @@ class EntityOperations {
*/ */
IndexCoordinates determineIndex(ElasticsearchPersistentEntity<?> persistentEntity, @Nullable String index, IndexCoordinates determineIndex(ElasticsearchPersistentEntity<?> persistentEntity, @Nullable String index,
@Nullable String type) { @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) { 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.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity; import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity;
import org.springframework.data.elasticsearch.core.EntityOperations.Entity; 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.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.DocumentAdapters;
@ -346,6 +345,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
searchSourceBuilder.size(pageable.getPageSize()); searchSourceBuilder.size(pageable.getPageSize());
request.source(searchSourceBuilder); request.source(searchSourceBuilder);
request.source(searchSourceBuilder);
} else if (query.isLimiting()) { } else if (query.isLimiting()) {
searchSourceBuilder.from(0); searchSourceBuilder.from(0);
searchSourceBuilder.size(query.getMaxResults()); searchSourceBuilder.size(query.getMaxResults());
@ -356,10 +356,6 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
} }
return request; return request;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#count(Query, Class, String, String)
*/
/* /*
* (non-Javadoc) * (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.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations; 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.ScoredPage;
import org.springframework.data.elasticsearch.core.ScrolledPage; import org.springframework.data.elasticsearch.core.ScrolledPage;
/** /**
* @author Petar Tahchiev * @author Petar Tahchiev
* @author Sascha Woo * @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(); boolean hasAggregations();

View File

@ -15,12 +15,14 @@
*/ */
package org.springframework.data.elasticsearch.core.aggregation.impl; package org.springframework.data.elasticsearch.core.aggregation.impl;
import static java.util.Optional.*;
import java.util.List; import java.util.List;
import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations; import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; 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.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse;
@ -31,12 +33,16 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentRespon
* @author Sascha Woo * @author Sascha Woo
* @author Peter-Josef Meisch * @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 Aggregations aggregations;
private String scrollId; private String scrollId;
private float maxScore; private float maxScore;
private static Pageable pageableOrUnpaged(Pageable pageable) {
return ofNullable(pageable).orElse(Pageable.unpaged());
}
public AggregatedPageImpl(List<T> content) { public AggregatedPageImpl(List<T> content) {
super(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) { 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) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, float maxScore) {
super(content, pageable, total); super(content, pageableOrUnpaged(pageable), total);
this.maxScore = maxScore; this.maxScore = maxScore;
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId) {
super(content, pageable, total); super(content, pageableOrUnpaged(pageable), total);
this.scrollId = scrollId; this.scrollId = scrollId;
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, String scrollId, float maxScore) { 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; this.maxScore = maxScore;
} }
public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) { public AggregatedPageImpl(List<T> content, Pageable pageable, long total, Aggregations aggregations) {
super(content, pageable, total); super(content, pageableOrUnpaged(pageable), total);
this.aggregations = aggregations; 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 Sascha Woo
* @author Oliver Gierke * @author Oliver Gierke
* @author Ivan Greene * @author Ivan Greene
* @author Peter-Josef Meisch
*/ */
public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> { public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, ElasticsearchPersistentProperty> {
@ -58,7 +59,7 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
boolean isCreateIndexAndMapping(); 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. * {@literal true}, {@link #getScoreProperty()} will return a non-{@literal null} value.
* *
* @return false when {@link ElasticsearchPersistentEntity} does not define a score property. * @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 Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class AliasBuilder { public class AliasBuilder {
private String indexName;
private String aliasName; private String aliasName;
private QueryBuilder filterBuilder; private QueryBuilder filterBuilder;
private Map<String, Object> filter; private Map<String, Object> filter;
@ -32,11 +32,6 @@ public class AliasBuilder {
private String indexRouting; private String indexRouting;
private String routing; private String routing;
public AliasBuilder withIndexName(String indexName) {
this.indexName = indexName;
return this;
}
public AliasBuilder withAliasName(String aliasName) { public AliasBuilder withAliasName(String aliasName) {
this.aliasName = aliasName; this.aliasName = aliasName;
return this; return this;
@ -69,7 +64,6 @@ public class AliasBuilder {
public AliasQuery build() { public AliasQuery build() {
AliasQuery aliasQuery = new AliasQuery(); AliasQuery aliasQuery = new AliasQuery();
aliasQuery.setIndexName(indexName);
aliasQuery.setAliasName(aliasName); aliasQuery.setAliasName(aliasName);
aliasQuery.setFilterBuilder(filterBuilder); aliasQuery.setFilterBuilder(filterBuilder);
aliasQuery.setFilter(filter); 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 * AliasQuery is useful for creating new alias or deleting existing ones
* *
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class AliasQuery { public class AliasQuery {
private String indexName;
private String aliasName; private String aliasName;
private QueryBuilder filterBuilder; private QueryBuilder filterBuilder;
private Map<String, Object> filter; private Map<String, Object> filter;
@ -34,14 +34,6 @@ public class AliasQuery {
private String indexRouting; private String indexRouting;
private String routing; private String routing;
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public String getAliasName() { public String getAliasName() {
return aliasName; return aliasName;
} }

View File

@ -22,12 +22,11 @@ import org.elasticsearch.index.query.QueryBuilder;
* *
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class DeleteQuery { public class DeleteQuery {
private QueryBuilder query; private QueryBuilder query;
private String index;
private String type;
private Integer pageSize; private Integer pageSize;
private Long scrollTimeInMillis; private Long scrollTimeInMillis;
@ -39,22 +38,6 @@ public class DeleteQuery {
this.query = query; 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() { public Integer getPageSize() {
return pageSize; return pageSize;
} }

View File

@ -28,8 +28,6 @@ public class IndexQuery {
private String id; private String id;
private Object object; private Object object;
private Long version; private Long version;
private String indexName;
private String type;
private String source; private String source;
private String parentId; private String parentId;
@ -57,22 +55,6 @@ public class IndexQuery {
this.version = version; 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() { public String getSource() {
return source; return source;
} }

View File

@ -20,14 +20,13 @@ package org.springframework.data.elasticsearch.core.query;
* *
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class IndexQueryBuilder { public class IndexQueryBuilder {
private String id; private String id;
private Object object; private Object object;
private Long version; private Long version;
private String indexName;
private String type;
private String source; private String source;
private String parentId; private String parentId;
@ -46,16 +45,6 @@ public class IndexQueryBuilder {
return this; 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) { public IndexQueryBuilder withSource(String source) {
this.source = source; this.source = source;
return this; return this;
@ -69,8 +58,6 @@ public class IndexQueryBuilder {
public IndexQuery build() { public IndexQuery build() {
IndexQuery indexQuery = new IndexQuery(); IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(id); indexQuery.setId(id);
indexQuery.setIndexName(indexName);
indexQuery.setType(type);
indexQuery.setObject(object); indexQuery.setObject(object);
indexQuery.setParentId(parentId); indexQuery.setParentId(parentId);
indexQuery.setSource(source); 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.collapse.CollapseBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/** /**
* NativeSearchQuery * NativeSearchQuery
@ -43,7 +42,6 @@ public class NativeSearchQuery extends AbstractQuery {
private List<SortBuilder> sorts; private List<SortBuilder> sorts;
private final List<ScriptField> scriptFields = new ArrayList<>(); private final List<ScriptField> scriptFields = new ArrayList<>();
private CollapseBuilder collapseBuilder; private CollapseBuilder collapseBuilder;
private List<FacetRequest> facets;
private List<AbstractAggregationBuilder> aggregations; private List<AbstractAggregationBuilder> aggregations;
private HighlightBuilder highlightBuilder; private HighlightBuilder highlightBuilder;
private HighlightBuilder.Field[] highlightFields; private HighlightBuilder.Field[] highlightFields;
@ -126,23 +124,6 @@ public class NativeSearchQuery extends AbstractQuery {
this.collapseBuilder = collapseBuilder; 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() { public List<AbstractAggregationBuilder> getAggregations() {
return aggregations; 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.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
/** /**
* NativeSearchQuery * NativeSearchQuery
@ -50,7 +49,6 @@ public class NativeSearchQueryBuilder {
private QueryBuilder filterBuilder; private QueryBuilder filterBuilder;
private List<ScriptField> scriptFields = new ArrayList<>(); private List<ScriptField> scriptFields = new ArrayList<>();
private List<SortBuilder> sortBuilders = new ArrayList<>(); private List<SortBuilder> sortBuilders = new ArrayList<>();
private List<FacetRequest> facetRequests = new ArrayList<>();
private List<AbstractAggregationBuilder> aggregationBuilders = new ArrayList<>(); private List<AbstractAggregationBuilder> aggregationBuilders = new ArrayList<>();
private HighlightBuilder highlightBuilder; private HighlightBuilder highlightBuilder;
private HighlightBuilder.Field[] highlightFields; private HighlightBuilder.Field[] highlightFields;
@ -99,11 +97,6 @@ public class NativeSearchQueryBuilder {
return this; return this;
} }
public NativeSearchQueryBuilder withFacet(FacetRequest facetRequest) {
facetRequests.add(facetRequest);
return this;
}
public NativeSearchQueryBuilder withHighlightBuilder(HighlightBuilder highlightBuilder) { public NativeSearchQueryBuilder withHighlightBuilder(HighlightBuilder highlightBuilder) {
this.highlightBuilder = highlightBuilder; this.highlightBuilder = highlightBuilder;
return this; return this;
@ -219,10 +212,6 @@ public class NativeSearchQueryBuilder {
nativeSearchQuery.setCollapseBuilder(collapseBuilder); nativeSearchQuery.setCollapseBuilder(collapseBuilder);
} }
if (!isEmpty(facetRequests)) {
nativeSearchQuery.setFacets(facetRequests);
}
if (!isEmpty(aggregationBuilders)) { if (!isEmpty(aggregationBuilders)) {
nativeSearchQuery.setAggregations(aggregationBuilders); nativeSearchQuery.setAggregations(aggregationBuilders);
} }

View File

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

View File

@ -21,14 +21,12 @@ import org.elasticsearch.action.update.UpdateRequest;
/** /**
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class UpdateQuery { public class UpdateQuery {
private String id; private String id;
private UpdateRequest updateRequest; private UpdateRequest updateRequest;
private String indexName;
private String type;
private Class clazz;
private boolean doUpsert; private boolean doUpsert;
public String getId() { public String getId() {
@ -47,30 +45,6 @@ public class UpdateQuery {
this.updateRequest = updateRequest; 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() { public boolean DoUpsert() {
return doUpsert; return doUpsert;
} }

View File

@ -21,15 +21,13 @@ import org.elasticsearch.action.update.UpdateRequest;
/** /**
* @author Rizwan Idrees * @author Rizwan Idrees
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
public class UpdateQueryBuilder { public class UpdateQueryBuilder {
private String id; private String id;
private UpdateRequest updateRequest; private UpdateRequest updateRequest;
private IndexRequest indexRequest; private IndexRequest indexRequest;
private String indexName;
private String type;
private Class clazz;
private boolean doUpsert; private boolean doUpsert;
public UpdateQueryBuilder withId(String id) { public UpdateQueryBuilder withId(String id) {
@ -47,21 +45,6 @@ public class UpdateQueryBuilder {
return this; 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) { public UpdateQueryBuilder withDoUpsert(boolean doUpsert) {
this.doUpsert = doUpsert; this.doUpsert = doUpsert;
return this; return this;
@ -70,9 +53,6 @@ public class UpdateQueryBuilder {
public UpdateQuery build() { public UpdateQuery build() {
UpdateQuery updateQuery = new UpdateQuery(); UpdateQuery updateQuery = new UpdateQuery();
updateQuery.setId(id); updateQuery.setId(id);
updateQuery.setIndexName(indexName);
updateQuery.setType(type);
updateQuery.setClazz(clazz);
if (this.indexRequest != null) { if (this.indexRequest != null) {
if (this.updateRequest == null) { if (this.updateRequest == null) {
updateRequest = new UpdateRequest(); 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.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; 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.mapping.ElasticsearchPersistentProperty;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator; import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator;
@ -57,6 +58,8 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
CriteriaQuery query = createQuery(accessor); CriteriaQuery query = createQuery(accessor);
Assert.notNull(query, "unsupported query"); Assert.notNull(query, "unsupported query");
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
if (tree.isLimiting()) { if (tree.isLimiting()) {
query.setMaxResults(tree.getMaxResults()); query.setMaxResults(tree.getMaxResults());
@ -64,55 +67,60 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery
if (tree.isDelete()) { if (tree.isDelete()) {
Object result = countOrGetDocumentsForDelete(query, accessor); Object result = countOrGetDocumentsForDelete(query, accessor);
elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType()); elasticsearchOperations.delete(query, clazz, index);
return result; return result;
} else if (queryMethod.isPageQuery()) { } else if (queryMethod.isPageQuery()) {
query.setPageable(accessor.getPageable()); query.setPageable(accessor.getPageable());
return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType()); return elasticsearchOperations.queryForPage(query, clazz, index);
} else if (queryMethod.isStreamQuery()) { } else if (queryMethod.isStreamQuery()) {
Class<?> entityType = queryMethod.getEntityInformation().getJavaType(); Class<?> entityType = clazz;
if (accessor.getPageable().isUnpaged()) { if (accessor.getPageable().isUnpaged()) {
query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE)); query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE));
} else { } else {
query.setPageable(accessor.getPageable()); query.setPageable(accessor.getPageable());
} }
return StreamUtils return StreamUtils
.createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType)); .createStreamFromIterator((CloseableIterator<Object>) elasticsearchOperations.stream(query, entityType, index));
} else if (queryMethod.isCollectionQuery()) { } else if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isUnpaged()) { if (accessor.getPageable().isUnpaged()) {
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); int itemCount = (int) elasticsearchOperations.count(query, clazz,
index);
query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
} else { } else {
query.setPageable(accessor.getPageable()); query.setPageable(accessor.getPageable());
} }
return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType()); return elasticsearchOperations.queryForList(query, clazz, index);
} else if (tree.isCountProjection()) { } 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) { private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) {
Object result = null; Object result = null;
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations
.getIndexCoordinatesFor(clazz);
if (queryMethod.isCollectionQuery()) { if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isUnpaged()) { if (accessor.getPageable().isUnpaged()) {
int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); int itemCount = (int) elasticsearchOperations.count(query, clazz,
index);
query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); query.setPageable(PageRequest.of(0, Math.max(1, itemCount)));
} else { } else {
query.setPageable(accessor.getPageable()); query.setPageable(accessor.getPageable());
} }
result = elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType()); result = elasticsearchOperations.queryForList(query, clazz, index);
} }
if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) { if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) {
result = elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); result = elasticsearchOperations.count(query, clazz, index);
} }
return result; return result;
} }

View File

@ -20,6 +20,7 @@ import java.util.regex.Pattern;
import org.springframework.core.convert.support.GenericConversionService; import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; 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.convert.DateTimeConverters;
import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.ParametersParameterAccessor;
@ -68,17 +69,19 @@ public class ElasticsearchStringQuery extends AbstractElasticsearchRepositoryQue
public Object execute(Object[] parameters) { public Object execute(Object[] parameters) {
ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters);
StringQuery stringQuery = createQuery(accessor); StringQuery stringQuery = createQuery(accessor);
Class<?> clazz = queryMethod.getEntityInformation().getJavaType();
IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz);
if (queryMethod.isPageQuery()) { if (queryMethod.isPageQuery()) {
stringQuery.setPageable(accessor.getPageable()); stringQuery.setPageable(accessor.getPageable());
return elasticsearchOperations.queryForPage(stringQuery, queryMethod.getEntityInformation().getJavaType()); return elasticsearchOperations.queryForPage(stringQuery, clazz, index);
} else if (queryMethod.isCollectionQuery()) { } else if (queryMethod.isCollectionQuery()) {
if (accessor.getPageable().isPaged()) { if (accessor.getPageable().isPaged()) {
stringQuery.setPageable(accessor.getPageable()); 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) { 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.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; 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.DeleteQuery;
import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -72,7 +73,6 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
public AbstractElasticsearchRepository() {} public AbstractElasticsearchRepository() {}
public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) { public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) {
Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!"); Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!");
this.setElasticsearchOperations(elasticsearchOperations); this.setElasticsearchOperations(elasticsearchOperations);
@ -80,7 +80,6 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
public AbstractElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metadata, public AbstractElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metadata,
ElasticsearchOperations elasticsearchOperations) { ElasticsearchOperations elasticsearchOperations) {
this(elasticsearchOperations); this(elasticsearchOperations);
Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!");
@ -98,124 +97,99 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
} }
private void createIndex() { private void createIndex() {
elasticsearchOperations.createIndex(getEntityClass()); elasticsearchOperations.createIndex(getEntityClass());
} }
private void putMapping() { private void putMapping() {
elasticsearchOperations.putMapping(getEntityClass()); elasticsearchOperations.putMapping(getEntityClass());
} }
private boolean createIndexAndMapping() { private boolean createIndexAndMapping() {
return elasticsearchOperations.getPersistentEntityFor(getEntityClass()).isCreateIndexAndMapping(); return elasticsearchOperations.getPersistentEntityFor(getEntityClass()).isCreateIndexAndMapping();
} }
@Override @Override
public Optional<T> findById(ID id) { public Optional<T> findById(ID id) {
GetQuery query = new GetQuery(); GetQuery query = new GetQuery();
query.setId(stringIdRepresentation(id)); query.setId(stringIdRepresentation(id));
return Optional.ofNullable(elasticsearchOperations.queryForObject(query, getEntityClass())); return Optional.ofNullable(elasticsearchOperations.get(query, getEntityClass(), getIndexCoordinates()));
} }
@Override @Override
public Iterable<T> findAll() { public Iterable<T> findAll() {
int itemCount = (int) this.count(); int itemCount = (int) this.count();
if (itemCount == 0) { if (itemCount == 0) {
return new PageImpl<>(Collections.<T> emptyList()); return new PageImpl<>(Collections.<T> emptyList());
} }
return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); return this.findAll(PageRequest.of(0, Math.max(1, itemCount)));
} }
@Override @Override
public Page<T> findAll(Pageable pageable) { public Page<T> findAll(Pageable pageable) {
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build();
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.queryForPage(query, getEntityClass());
} }
@Override @Override
public Iterable<T> findAll(Sort sort) { public Iterable<T> findAll(Sort sort) {
int itemCount = (int) this.count(); int itemCount = (int) this.count();
if (itemCount == 0) { if (itemCount == 0) {
return new PageImpl<>(Collections.<T> emptyList()); return new PageImpl<>(Collections.<T> emptyList());
} }
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withPageable(PageRequest.of(0, itemCount, sort)).build(); .withPageable(PageRequest.of(0, itemCount, sort)).build();
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.queryForPage(query, getEntityClass());
} }
@Override @Override
public Iterable<T> findAllById(Iterable<ID> ids) { public Iterable<T> findAllById(Iterable<ID> ids) {
Assert.notNull(ids, "ids can't be null."); Assert.notNull(ids, "ids can't be null.");
NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build();
return elasticsearchOperations.multiGet(query, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.multiGet(query, getEntityClass());
} }
@Override @Override
public long count() { public long count() {
NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
return elasticsearchOperations.count(query, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.count(query, getEntityClass());
} }
@Override @Override
public <S extends T> S save(S entity) { public <S extends T> S save(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity."); Assert.notNull(entity, "Cannot save 'null' entity.");
elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates());
elasticsearchOperations.index(createIndexQuery(entity)); elasticsearchOperations.refresh(getIndexCoordinates());
elasticsearchOperations.refresh(entityInformation.getIndexName());
return entity; return entity;
} }
public <S extends T> List<S> save(List<S> entities) { public <S extends T> List<S> save(List<S> entities) {
Assert.notNull(entities, "Cannot insert 'null' as a List."); Assert.notNull(entities, "Cannot insert 'null' as a List.");
return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList());
} }
@Override @Override
public <S extends T> S index(S entity) { public <S extends T> S index(S entity) {
return save(entity); return save(entity);
} }
@Override @Override
public <S extends T> S indexWithoutRefresh(S entity) { public <S extends T> S indexWithoutRefresh(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity."); Assert.notNull(entity, "Cannot save 'null' entity.");
elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates());
elasticsearchOperations.index(createIndexQuery(entity));
return entity; return entity;
} }
@Override @Override
public <S extends T> Iterable<S> saveAll(Iterable<S> entities) { public <S extends T> Iterable<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "Cannot insert 'null' as a List."); Assert.notNull(entities, "Cannot insert 'null' as a List.");
List<IndexQuery> queries = Streamable.of(entities).stream().map(this::createIndexQuery) List<IndexQuery> queries = Streamable.of(entities).stream().map(this::createIndexQuery)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!queries.isEmpty()) { if (!queries.isEmpty()) {
elasticsearchOperations.bulkIndex(queries); elasticsearchOperations.bulkIndex(queries, getIndexCoordinates());
elasticsearchOperations.refresh(entityInformation.getIndexName()); elasticsearchOperations.refresh(getIndexCoordinates());
} }
return entities; return entities;
@ -223,76 +197,64 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@Override @Override
public boolean existsById(ID id) { public boolean existsById(ID id) {
return findById(id).isPresent(); return findById(id).isPresent();
} }
@Override @Override
public Iterable<T> search(QueryBuilder query) { public Iterable<T> search(QueryBuilder query) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); 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) { if (count == 0) {
return new PageImpl<>(Collections.<T> emptyList()); return new PageImpl<>(Collections.<T> emptyList());
} }
searchQuery.setPageable(PageRequest.of(0, count)); searchQuery.setPageable(PageRequest.of(0, count));
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass());
} }
@Override @Override
public Page<T> search(QueryBuilder query, Pageable pageable) { public Page<T> search(QueryBuilder query, Pageable pageable) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build();
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.queryForPage(searchQuery, getEntityClass());
} }
@Override @Override
public Page<T> search(NativeSearchQuery query) { public Page<T> search(NativeSearchQuery query) {
return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates());
return elasticsearchOperations.queryForPage(query, getEntityClass());
} }
@Override @Override
public Page<T> searchSimilar(T entity, String[] fields, Pageable pageable) { public Page<T> searchSimilar(T entity, String[] fields, Pageable pageable) {
Assert.notNull(entity, "Cannot search similar records for 'null'."); Assert.notNull(entity, "Cannot search similar records for 'null'.");
Assert.notNull(pageable, "'pageable' cannot be 'null'"); Assert.notNull(pageable, "'pageable' cannot be 'null'");
MoreLikeThisQuery query = new MoreLikeThisQuery(); MoreLikeThisQuery query = new MoreLikeThisQuery();
query.setId(stringIdRepresentation(extractIdFromBean(entity))); query.setId(stringIdRepresentation(extractIdFromBean(entity)));
query.setPageable(pageable); query.setPageable(pageable);
if (fields != null) { if (fields != null) {
query.addFields(fields); query.addFields(fields);
} }
return elasticsearchOperations.moreLikeThis(query, getEntityClass()); return elasticsearchOperations.moreLikeThis(query, getEntityClass(), getIndexCoordinates());
} }
@Override @Override
public void deleteById(ID id) { public void deleteById(ID id) {
Assert.notNull(id, "Cannot delete entity with id 'null'."); Assert.notNull(id, "Cannot delete entity with id 'null'.");
IndexCoordinates indexCoordinates = getIndexCoordinates();
elasticsearchOperations.delete(entityInformation.getIndexName(), entityInformation.getType(), elasticsearchOperations.delete(stringIdRepresentation(id), indexCoordinates);
stringIdRepresentation(id)); elasticsearchOperations.refresh(indexCoordinates);
elasticsearchOperations.refresh(entityInformation.getIndexName());
} }
@Override @Override
public void delete(T entity) { public void delete(T entity) {
Assert.notNull(entity, "Cannot delete 'null' entity."); Assert.notNull(entity, "Cannot delete 'null' entity.");
deleteById(extractIdFromBean(entity)); deleteById(extractIdFromBean(entity));
elasticsearchOperations.refresh(entityInformation.getIndexName()); elasticsearchOperations.refresh(getIndexCoordinates());
} }
@Override @Override
public void deleteAll(Iterable<? extends T> entities) { public void deleteAll(Iterable<? extends T> entities) {
Assert.notNull(entities, "Cannot delete 'null' list."); Assert.notNull(entities, "Cannot delete 'null' list.");
for (T entity : entities) { for (T entity : entities) {
delete(entity); delete(entity);
@ -301,21 +263,19 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@Override @Override
public void deleteAll() { public void deleteAll() {
DeleteQuery deleteQuery = new DeleteQuery(); DeleteQuery deleteQuery = new DeleteQuery();
deleteQuery.setQuery(matchAllQuery()); deleteQuery.setQuery(matchAllQuery());
elasticsearchOperations.delete(deleteQuery, getEntityClass()); IndexCoordinates indexCoordinates = getIndexCoordinates();
elasticsearchOperations.refresh(entityInformation.getIndexName()); elasticsearchOperations.delete(deleteQuery, indexCoordinates);
elasticsearchOperations.refresh(indexCoordinates);
} }
@Override @Override
public void refresh() { public void refresh() {
elasticsearchOperations.refresh(getEntityClass()); elasticsearchOperations.refresh(getEntityClass());
} }
private IndexQuery createIndexQuery(T entity) { private IndexQuery createIndexQuery(T entity) {
IndexQuery query = new IndexQuery(); IndexQuery query = new IndexQuery();
query.setObject(entity); query.setObject(entity);
query.setId(stringIdRepresentation(extractIdFromBean(entity))); query.setId(stringIdRepresentation(extractIdFromBean(entity)));
@ -326,14 +286,13 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Class<T> resolveReturnedClassFromGenericType() { private Class<T> resolveReturnedClassFromGenericType() {
ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass()); ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass());
return (Class<T>) parameterizedType.getActualTypeArguments()[0]; return (Class<T>) parameterizedType.getActualTypeArguments()[0];
} }
private ParameterizedType resolveReturnedClassFromGenericType(Class<?> clazz) { private ParameterizedType resolveReturnedClassFromGenericType(Class<?> clazz) {
Object genericSuperclass = clazz.getGenericSuperclass(); Object genericSuperclass = clazz.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) { if (genericSuperclass instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
Type rawtype = parameterizedType.getRawType(); 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); throw new InvalidDataAccessApiUsageException("Unable to resolve EntityClass. Please use according setter!", e);
} }
} }
return entityClass; return entityClass;
} }
private boolean isEntityClassSet() { private boolean isEntityClassSet() {
return entityClass != null; return entityClass != null;
} }
public final void setEntityClass(Class<T> entityClass) { public final void setEntityClass(Class<T> entityClass) {
Assert.notNull(entityClass, "EntityClass must not be null."); Assert.notNull(entityClass, "EntityClass must not be null.");
this.entityClass = entityClass; this.entityClass = entityClass;
} }
public final void setElasticsearchOperations(ElasticsearchOperations elasticsearchOperations) { public final void setElasticsearchOperations(ElasticsearchOperations elasticsearchOperations) {
Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null."); Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null.");
this.elasticsearchOperations = elasticsearchOperations; this.elasticsearchOperations = elasticsearchOperations;
} }
@ -382,9 +336,7 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
} }
private List<String> stringIdsRepresentation(Iterable<ID> ids) { private List<String> stringIdsRepresentation(Iterable<ID> ids) {
Assert.notNull(ids, "ids can't be null."); Assert.notNull(ids, "ids can't be null.");
List<String> stringIds = new ArrayList<>(); List<String> stringIds = new ArrayList<>();
for (ID id : ids) { for (ID id : ids) {
stringIds.add(stringIdRepresentation(id)); stringIds.add(stringIdRepresentation(id));
@ -402,4 +354,8 @@ public abstract class AbstractElasticsearchRepository<T, ID> implements Elastics
private String extractParentIdFromBean(T entity) { private String extractParentIdFromBean(T entity) {
return entityInformation.getParentId(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.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
@ -122,14 +123,15 @@ public class NestedObjectTests {
indexQueries.add(indexQuery1); indexQueries.add(indexQuery1);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Person.class); elasticsearchTemplate.refresh(Person.class);
QueryBuilder builder = nestedQuery("car", QueryBuilder builder = nestedQuery("car",
boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); 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); assertThat(persons).hasSize(1);
} }
@ -141,14 +143,15 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson(); List<IndexQuery> indexQueries = createPerson();
// when // when
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class);
// then // then
GetQuery getQuery = new GetQuery(); GetQuery getQuery = new GetQuery();
getQuery.setId("1"); getQuery.setId("1");
PersonMultipleLevelNested personIndexed = elasticsearchTemplate.queryForObject(getQuery, PersonMultipleLevelNested personIndexed = elasticsearchTemplate.get(getQuery, PersonMultipleLevelNested.class,
PersonMultipleLevelNested.class); IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
assertThat(personIndexed).isNotNull(); assertThat(personIndexed).isNotNull();
} }
@ -159,7 +162,8 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson(); List<IndexQuery> indexQueries = createPerson();
// when // when
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries,
IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"));
// then // then
Map<String, Object> mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class); Map<String, Object> mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class);
@ -178,7 +182,9 @@ public class NestedObjectTests {
List<IndexQuery> indexQueries = createPerson(); List<IndexQuery> indexQueries = createPerson();
// when // when
elasticsearchTemplate.bulkIndex(indexQueries); IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries,
index);
elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class);
// then // then
@ -189,7 +195,7 @@ public class NestedObjectTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
Page<PersonMultipleLevelNested> personIndexed = elasticsearchTemplate.queryForPage(searchQuery, Page<PersonMultipleLevelNested> personIndexed = elasticsearchTemplate.queryForPage(searchQuery,
PersonMultipleLevelNested.class); PersonMultipleLevelNested.class, index);
assertThat(personIndexed).isNotNull(); assertThat(personIndexed).isNotNull();
assertThat(personIndexed.getTotalElements()).isEqualTo(1); assertThat(personIndexed.getTotalElements()).isEqualTo(1);
assertThat(personIndexed.getContent().get(0).getId()).isEqualTo("1"); assertThat(personIndexed.getContent().get(0).getId()).isEqualTo("1");
@ -317,14 +323,15 @@ public class NestedObjectTests {
indexQueries.add(indexQuery1); indexQueries.add(indexQuery1);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Person.class); elasticsearchTemplate.refresh(Person.class);
// when // when
QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); 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 // then
assertThat(persons).hasSize(1); assertThat(persons).hasSize(1);
@ -365,13 +372,14 @@ public class NestedObjectTests {
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
// when // when
elasticsearchTemplate.bulkIndex(indexQueries); IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes( "book");
elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(Book.class); elasticsearchTemplate.refresh(Book.class);
// then // then
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); .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()).hasSize(1);
assertThat(books.getContent().get(0).getId()).isEqualTo(book2.getId()); 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.Builder;
import lombok.Data; 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.ElasticsearchStatusException;
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document; 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.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.util.ReflectionTestUtils;
/** /**
* @author Rizwan Idrees * @author Rizwan Idrees
@ -56,7 +48,6 @@ import org.springframework.test.util.ReflectionTestUtils;
* @author Sascha Woo * @author Sascha Woo
* @author Don Wellington * @author Don Wellington
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @author Massimiliano Poggi
*/ */
@SpringIntegrationTest @SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
@ -68,65 +59,12 @@ public class ElasticsearchRestTemplateTests extends ElasticsearchTemplateTests {
// when // when
IndexRequest indexRequest = new IndexRequest(); IndexRequest indexRequest = new IndexRequest();
indexRequest.source("{}", XContentType.JSON); indexRequest.source("{}", XContentType.JSON);
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class) UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build();
.withIndexRequest(indexRequest).build();
assertThatThrownBy(() -> { assertThatThrownBy(() -> {
elasticsearchTemplate.update(updateQuery); elasticsearchTemplate.update(updateQuery, index);
}).isInstanceOf(ElasticsearchStatusException.class); }).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 @Data
@Builder @Builder
@Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0, @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 // find all parents that have the first child
QueryBuilder query = hasChildQuery(ParentEntity.CHILD_TYPE, QueryBuilder query = hasChildQuery(ParentEntity.CHILD_TYPE,
QueryBuilders.termQuery("name", child1name.toLowerCase()), ScoreMode.None); 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 // we're expecting only the first parent as result
assertThat(parents).hasSize(1); assertThat(parents).hasSize(1);
@ -105,7 +105,7 @@ public class ElasticsearchTemplateParentChildTests {
XContentBuilder builder; XContentBuilder builder;
builder = jsonBuilder().startObject().field("name", newChildName).endObject(); builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder); 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); assertThat(response.getShardInfo().getSuccessful()).isEqualTo(1);
} }
@ -124,7 +124,7 @@ public class ElasticsearchTemplateParentChildTests {
XContentBuilder builder; XContentBuilder builder;
builder = jsonBuilder().startObject().field("name", newChildName).endObject(); builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder); updateRequest.doc(builder);
update(updateRequest); update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
} }
@Ignore(value = "DATAES-421") @Ignore(value = "DATAES-421")
@ -142,7 +142,7 @@ public class ElasticsearchTemplateParentChildTests {
builder = jsonBuilder().startObject().field("name", newChildName).endObject(); builder = jsonBuilder().startObject().field("name", newChildName).endObject();
updateRequest.doc(builder); updateRequest.doc(builder);
updateRequest.doc().routing(parent.getId()); updateRequest.doc().routing(parent.getId());
update(updateRequest); update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
} }
private ParentEntity index(String parentId, String name) { private ParentEntity index(String parentId, String name) {
@ -151,7 +151,7 @@ public class ElasticsearchTemplateParentChildTests {
IndexQuery index = new IndexQuery(); IndexQuery index = new IndexQuery();
index.setId(parent.getId()); index.setId(parent.getId());
index.setObject(parent); index.setObject(parent);
elasticsearchTemplate.index(index); elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.PARENT_TYPE));
return parent; return parent;
} }
@ -163,19 +163,17 @@ public class ElasticsearchTemplateParentChildTests {
index.setId(child.getId()); index.setId(child.getId());
index.setObject(child); index.setObject(child);
index.setParentId(child.getParentId()); index.setParentId(child.getParentId());
elasticsearchTemplate.index(index); elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE));
return child; return child;
} }
private UpdateResponse update(UpdateRequest updateRequest) { private UpdateResponse update(UpdateRequest updateRequest, IndexCoordinates index) {
UpdateQuery update = new UpdateQuery(); UpdateQuery update = new UpdateQuery();
update.setId(updateRequest.id()); update.setId(updateRequest.id());
update.setType(updateRequest.type());
update.setIndexName(updateRequest.index());
update.setUpdateRequest(updateRequest); update.setUpdateRequest(updateRequest);
return elasticsearchTemplate.update(update); return elasticsearchTemplate.update(update, index);
} }
/** /**

View File

@ -46,10 +46,9 @@ public class ElasticsearchTransportTemplateTests extends ElasticsearchTemplateTe
// when // when
IndexRequest indexRequest = new IndexRequest(); IndexRequest indexRequest = new IndexRequest();
indexRequest.source("{}", XContentType.JSON); indexRequest.source("{}", XContentType.JSON);
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class) UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build();
.withIndexRequest(indexRequest).build();
assertThatThrownBy(() -> { assertThatThrownBy(() -> {
elasticsearchTemplate.update(updateQuery); elasticsearchTemplate.update(updateQuery, index);
}).isInstanceOf(DocumentMissingException.class); }).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 }) @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class LogEntityTests { public class LogEntityTests {
private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes( "test-log-type");
@Autowired private ElasticsearchTemplate template; @Autowired private ElasticsearchTemplate template;
@BeforeEach @BeforeEach
@ -73,7 +74,7 @@ public class LogEntityTests {
IndexQuery indexQuery4 = new LogEntityBuilder("4").action("update").date(dateFormatter.parse("2013-10-19 18:04")) IndexQuery indexQuery4 = new LogEntityBuilder("4").action("update").date(dateFormatter.parse("2013-10-19 18:04"))
.code(2).ip("10.10.10.4").buildIndex(); .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); template.refresh(LogEntity.class);
} }
@ -82,7 +83,7 @@ public class LogEntityTests {
// when // when
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); 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 // then
assertThat(entities).isNotNull().hasSize(1); assertThat(entities).isNotNull().hasSize(1);
@ -95,7 +96,7 @@ public class LogEntityTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build();
assertThatThrownBy(() -> { assertThatThrownBy(() -> {
List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class); List<LogEntity> entities = template.queryForList(searchQuery, LogEntity.class, index);
}).isInstanceOf(SearchPhaseExecutionException.class); }).isInstanceOf(SearchPhaseExecutionException.class);
} }
@ -105,7 +106,7 @@ public class LogEntityTests {
// when // when
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build(); .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 // then
assertThat(entities).isNotNull().hasSize(3); 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.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; 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.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -76,7 +74,6 @@ import org.springframework.util.StringUtils;
* @author Martin Choraine * @author Martin Choraine
*/ */
@SpringIntegrationTest @SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class })
public class ReactiveElasticsearchTemplateTests { public class ReactiveElasticsearchTemplateTests {
static final String DEFAULT_INDEX = "reactive-template-test-index"; static final String DEFAULT_INDEX = "reactive-template-test-index";
@ -139,8 +136,9 @@ public class ReactiveElasticsearchTemplateTests {
restTemplate.refresh(SampleEntity.class); restTemplate.refresh(SampleEntity.class);
List<SampleEntity> result = restTemplate List<SampleEntity> result = restTemplate.queryForList(
.queryForList(new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class); new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class,
IndexCoordinates.of(DEFAULT_INDEX));
assertThat(result).hasSize(1); assertThat(result).hasSize(1);
} }
@ -171,8 +169,8 @@ public class ReactiveElasticsearchTemplateTests {
.expectNextCount(1)// .expectNextCount(1)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(DEFAULT_INDEX); restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX));
restTemplate.refresh(ALTERNATE_INDEX); restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX));
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse(); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse();
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue(); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue();
@ -192,8 +190,9 @@ public class ReactiveElasticsearchTemplateTests {
@Test // DATAES-504 @Test // DATAES-504
public void insertShouldErrorOnNullEntity() { public void insertShouldErrorOnNullEntity() {
assertThatThrownBy(() -> template.save(null)).isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> {
template.save(null);
}).isInstanceOf(IllegalArgumentException.class);
} }
@Test // DATAES-519 @Test // DATAES-519
@ -245,7 +244,9 @@ public class ReactiveElasticsearchTemplateTests {
@Test // DATAES-504 @Test // DATAES-504
public void findByIdShouldErrorForNullId() { public void findByIdShouldErrorForNullId() {
assertThatThrownBy(() -> template.findById(null, SampleEntity.class)).isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> {
template.findById(null, SampleEntity.class);
}).isInstanceOf(IllegalArgumentException.class);
} }
@Test // DATAES-504 @Test // DATAES-504
@ -254,13 +255,12 @@ public class ReactiveElasticsearchTemplateTests {
SampleEntity sampleEntity = randomEntity("some message"); SampleEntity sampleEntity = randomEntity("some message");
IndexQuery indexQuery = getIndexQuery(sampleEntity); 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(SampleEntity.class);
restTemplate.refresh(DEFAULT_INDEX); restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX));
restTemplate.refresh(ALTERNATE_INDEX); restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX));
template.findById(sampleEntity.getId(), SampleEntity.class) // template.findById(sampleEntity.getId(), SampleEntity.class) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -586,8 +586,8 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)// .as(StepVerifier::create)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(thisIndex); restTemplate.refresh(IndexCoordinates.of(thisIndex));
restTemplate.refresh(thatIndex); restTemplate.refresh(IndexCoordinates.of(thatIndex));
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "test")) // .withQuery(termQuery("message", "test")) //
@ -616,8 +616,8 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)// .as(StepVerifier::create)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(thisIndex); restTemplate.refresh(IndexCoordinates.of(thisIndex));
restTemplate.refresh(thatIndex); restTemplate.refresh(IndexCoordinates.of(thatIndex));
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "negative")) // .withQuery(termQuery("message", "negative")) //
@ -725,10 +725,12 @@ public class ReactiveElasticsearchTemplateTests {
private void index(SampleEntity... entities) { private void index(SampleEntity... entities) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes( "test-type");
if (entities.length == 1) { if (entities.length == 1) {
restTemplate.index(getIndexQuery(entities[0])); restTemplate.index(getIndexQuery(entities[0]), indexCoordinates);
} else { } else {
restTemplate.bulkIndex(getIndexQueries(entities)); restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates);
} }
restTemplate.refresh(SampleEntity.class); 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.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; 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) .addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000)
.score(40).buildIndex(); .score(40).buildIndex();
elasticsearchTemplate.index(article1); IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes( "article");
elasticsearchTemplate.index(article2); elasticsearchTemplate.index(article1, index);
elasticsearchTemplate.index(article3); elasticsearchTemplate.index(article2, index);
elasticsearchTemplate.index(article4); elasticsearchTemplate.index(article3, index);
elasticsearchTemplate.index(article4, index);
elasticsearchTemplate.refresh(ArticleEntity.class); elasticsearchTemplate.refresh(ArticleEntity.class);
} }
@ -118,7 +120,7 @@ public class ElasticsearchTemplateAggregationTests {
public Aggregations extract(SearchResponse response) { public Aggregations extract(SearchResponse response) {
return response.getAggregations(); return response.getAggregations();
} }
}); }, null, IndexCoordinates.of(INDEX_NAME).withTypes("article"));
// then // then
assertThat(aggregations).isNotNull(); assertThat(aggregations).isNotNull();
assertThat(aggregations.asMap().get("subjects")).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.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.core.query.IndexQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; 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" }) indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[] { "Artur", "Konczak" })
.buildIndex()); .buildIndex());
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type"));
elasticsearchTemplate.refresh(CompletionEntity.class); elasticsearchTemplate.refresh(CompletionEntity.class);
} }
@ -88,7 +89,8 @@ public class ElasticsearchTemplateCompletionTests {
indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak") indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak")
.suggest(new String[] { "Artur", "Konczak" }).buildIndex()); .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); elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class);
} }
@ -106,7 +108,8 @@ public class ElasticsearchTemplateCompletionTests {
indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4") indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4")
.suggest(new String[] { "Mewes Kochheim4" }, Integer.MAX_VALUE).buildIndex()); .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); elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class);
} }
@ -132,7 +135,8 @@ public class ElasticsearchTemplateCompletionTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( 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"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -152,7 +156,8 @@ public class ElasticsearchTemplateCompletionTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( 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"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -173,7 +178,7 @@ public class ElasticsearchTemplateCompletionTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), 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"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); 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.CompletionField;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.core.query.IndexQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
@ -86,7 +87,8 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak") indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak")
.suggest(new String[] { "Artur", "Konczak" }, context4).buildIndex()); .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); elasticsearchTemplate.refresh(ContextCompletionEntity.class);
} }
@ -123,7 +125,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class); IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull(); assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -155,7 +157,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class); IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull(); assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
@ -187,7 +189,7 @@ public class ElasticsearchTemplateCompletionWithContextsTests {
// when // when
SearchResponse suggestResponse = elasticsearchTemplate.suggest( SearchResponse suggestResponse = elasticsearchTemplate.suggest(
new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder),
ContextCompletionEntity.class); IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type"));
assertThat(suggestResponse.getSuggest()).isNotNull(); assertThat(suggestResponse.getSuggest()).isNotNull();
CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
List<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions(); 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.Document;
import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -61,6 +62,11 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class ElasticsearchTemplateGeoTests { 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; @Autowired private ElasticsearchTemplate elasticsearchTemplate;
@BeforeEach @BeforeEach
@ -77,7 +83,7 @@ public class ElasticsearchTemplateGeoTests {
.add(new AuthorMarkerEntityBuilder("1").name("Franck Marchand").location(45.7806d, 3.0875d).buildIndex()); .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("2").name("Mohsin Husen").location(51.5171d, 0.1062d).buildIndex());
indexQueries.add(new AuthorMarkerEntityBuilder("3").name("Rizwan Idrees").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); elasticsearchTemplate.refresh(AuthorMarkerEntity.class);
} }
@ -109,7 +115,7 @@ public class ElasticsearchTemplateGeoTests {
indexQueries.add(buildIndex(location2)); indexQueries.add(buildIndex(location2));
indexQueries.add(buildIndex(location3)); indexQueries.add(buildIndex(location3));
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, locationMarkerIndex);
elasticsearchTemplate.refresh(LocationMarkerEntity.class); elasticsearchTemplate.refresh(LocationMarkerEntity.class);
} }
@ -134,7 +140,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(1); assertThat(geoAuthorsForGeoCriteria).hasSize(1);
@ -151,7 +157,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria2 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery2, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria2 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery2,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria2).hasSize(1); assertThat(geoAuthorsForGeoCriteria2).hasSize(1);
@ -167,7 +173,7 @@ public class ElasticsearchTemplateGeoTests {
new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km")); new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km"));
// when // when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(1); assertThat(geoAuthorsForGeoCriteria).hasSize(1);
@ -183,7 +189,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(3); assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -198,7 +204,7 @@ public class ElasticsearchTemplateGeoTests {
new Criteria("locationAsArray").within("51.001000, 0.10100", "1km")); new Criteria("locationAsArray").within("51.001000, 0.10100", "1km"));
// when // when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(3); assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -213,7 +219,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery,
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(3); assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -229,7 +235,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(queryBuilder.build(), List<LocationMarkerEntity> geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(queryBuilder.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria).hasSize(3); assertThat(geoAuthorsForGeoCriteria).hasSize(3);
@ -245,7 +251,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2); assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -263,7 +269,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2); assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -281,7 +287,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2); assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -299,7 +305,7 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, List<AuthorMarkerEntity> geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3,
AuthorMarkerEntity.class); AuthorMarkerEntity.class, authorMarkerIndex);
// then // then
assertThat(geoAuthorsForGeoCriteria3).hasSize(2); assertThat(geoAuthorsForGeoCriteria3).hasSize(2);
@ -327,17 +333,17 @@ public class ElasticsearchTemplateGeoTests {
// when // when
List<LocationMarkerEntity> result1 = elasticsearchTemplate.queryForList(location1.build(), List<LocationMarkerEntity> result1 = elasticsearchTemplate.queryForList(location1.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result2 = elasticsearchTemplate.queryForList(location2.build(), List<LocationMarkerEntity> result2 = elasticsearchTemplate.queryForList(location2.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result3 = elasticsearchTemplate.queryForList(location3.build(), List<LocationMarkerEntity> result3 = elasticsearchTemplate.queryForList(location3.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result4 = elasticsearchTemplate.queryForList(location4.build(), List<LocationMarkerEntity> result4 = elasticsearchTemplate.queryForList(location4.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result5 = elasticsearchTemplate.queryForList(location5.build(), List<LocationMarkerEntity> result5 = elasticsearchTemplate.queryForList(location5.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
List<LocationMarkerEntity> result11 = elasticsearchTemplate.queryForList(location11.build(), List<LocationMarkerEntity> result11 = elasticsearchTemplate.queryForList(location11.build(),
LocationMarkerEntity.class); LocationMarkerEntity.class, locationMarkerIndex);
// then // then
assertThat(result1).hasSize(3); 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.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; 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.completion.Completion;
import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery;
@ -139,12 +140,16 @@ public class MappingBuilderTests extends MappingContextBaseTests {
double price = 2.34; double price = 2.34;
String id = "abc"; String id = "abc";
elasticsearchTemplate IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes( "price");
.index(buildIndex(StockPrice.builder().id(id).symbol(symbol).price(BigDecimal.valueOf(price)).build())); elasticsearchTemplate.index(buildIndex(StockPrice.builder() //
.id(id) //
.symbol(symbol) //
.price(BigDecimal.valueOf(price)) //
.build()), index);
elasticsearchTemplate.refresh(StockPrice.class); elasticsearchTemplate.refresh(StockPrice.class);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); 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 // Then
assertThat(result).hasSize(1); assertThat(result).hasSize(1);
@ -186,12 +191,14 @@ public class MappingBuilderTests extends MappingContextBaseTests {
Date createdDate = new Date(); Date createdDate = new Date();
String message = "msg"; String message = "msg";
String id = "abc"; String id = "abc";
elasticsearchTemplate IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes( "mapping");
.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex()); elasticsearchTemplate.index(
new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(),
index);
elasticsearchTemplate.refresh(SampleInheritedEntity.class); elasticsearchTemplate.refresh(SampleInheritedEntity.class);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); 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 // then
assertThat(result).hasSize(1); 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.Field;
import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
@ -54,6 +55,7 @@ import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class })
public class CriteriaQueryTests { public class CriteriaQueryTests {
private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes( "test-type");
@Autowired private ElasticsearchTemplate elasticsearchTemplate; @Autowired private ElasticsearchTemplate elasticsearchTemplate;
@BeforeEach @BeforeEach
@ -78,13 +80,13 @@ public class CriteriaQueryTests {
IndexQuery indexQuery = new IndexQuery(); IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(documentId); indexQuery.setId(documentId);
indexQuery.setObject(sampleEntity); indexQuery.setObject(sampleEntity);
elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.index(indexQuery, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery( CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("test").and("message").contains("some")); new Criteria("message").contains("test").and("message").contains("some"));
// when // when
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(sampleEntity1).isNotNull(); assertThat(sampleEntity1).isNotNull();
@ -121,13 +123,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery( CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("some").or("message").contains("test")); new Criteria("message").contains("some").or("message").contains("test"));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -152,13 +154,13 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity); indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery); indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some")));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -184,12 +186,12 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity); indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery); indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some")));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -213,12 +215,12 @@ public class CriteriaQueryTests {
indexQuery.setObject(sampleEntity); indexQuery.setObject(sampleEntity);
indexQueries.add(indexQuery); indexQueries.add(indexQuery);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message"));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -255,12 +257,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message"));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -297,13 +299,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
Criteria criteria = new Criteria("message").endsWith("end"); Criteria criteria = new Criteria("message").endsWith("end");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -339,13 +341,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
Criteria criteria = new Criteria("message").startsWith("start"); Criteria criteria = new Criteria("message").startsWith("start");
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria);
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -381,12 +383,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains"));
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -422,12 +424,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test"));
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -463,13 +465,13 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery( CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search"));
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message");
@ -505,12 +507,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not());
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(criteriaQuery.getCriteria().isNegating()).isTrue(); assertThat(criteriaQuery.getCriteria().isNegating()).isTrue();
@ -549,12 +551,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150));
// when // when
SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(sampleEntity).isNotNull(); assertThat(sampleEntity).isNotNull();
@ -591,12 +593,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -634,12 +636,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -677,12 +679,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -720,12 +722,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page).isNotNull(); assertThat(page).isNotNull();
@ -763,12 +765,12 @@ public class CriteriaQueryTests {
indexQuery2.setObject(sampleEntity2); indexQuery2.setObject(sampleEntity2);
indexQueries.add(indexQuery2); indexQueries.add(indexQuery2);
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1));
// when // when
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); 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("2").message("bc").build()));
indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build()));
elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.bulkIndex(indexQueries, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
// when // when
CriteriaQuery criteriaQuery = new CriteriaQuery( CriteriaQuery criteriaQuery = new CriteriaQuery(
new Criteria("message").contains("a").or(new Criteria("message").contains("b"))); new Criteria("message").contains("a").or(new Criteria("message").contains("b")));
criteriaQuery.setMinScore(2.0F); criteriaQuery.setMinScore(2.0F);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); Page<SampleEntity> page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(page.getTotalElements()).isEqualTo(1); assertThat(page.getTotalElements()).isEqualTo(1);
@ -811,13 +813,13 @@ public class CriteriaQueryTests {
IndexQuery indexQuery = new IndexQuery(); IndexQuery indexQuery = new IndexQuery();
indexQuery.setId(documentId); indexQuery.setId(documentId);
indexQuery.setObject(sampleEntity); indexQuery.setObject(sampleEntity);
elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.index(indexQuery, index);
elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class);
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!"));
// when // when
SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index);
// then // then
assertThat(sampleEntity1).isNotNull(); 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.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
@ -107,9 +108,11 @@ public class DynamicSettingAndMappingEntityRepositoryTests {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build(); .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, List<DynamicSettingAndMappingEntity> entityList = elasticsearchTemplate.queryForList(searchQuery,
DynamicSettingAndMappingEntity.class); DynamicSettingAndMappingEntity.class, index);
// then // then
assertThat(count).isEqualTo(1L); 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.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; 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.NativeSearchQuery;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
@ -70,7 +71,7 @@ public class SpELEntityTests {
// then // then
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
nativeSearchQuery.addIndices("test-index-abz-entity"); 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); assertThat(count).isEqualTo(2);
} }
@ -87,7 +88,7 @@ public class SpELEntityTests {
NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery());
nativeSearchQuery.addIndices("test-index-abz-entity"); nativeSearchQuery.addIndices("test-index-abz-entity");
nativeSearchQuery.addTypes("myType"); nativeSearchQuery.addTypes("myType");
long count = template.count(nativeSearchQuery); long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity"));
assertThat(count).isEqualTo(1); assertThat(count).isEqualTo(1);
} }

View File

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