Skip to content

Overload multiSearch method to support list of IndexCoordinates #2436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
* Elasticsearch client.
*
* @author Peter-Josef Meisch
* @author Hamid Rahimi
* @since 4.4
*/
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
Expand Down Expand Up @@ -465,6 +466,29 @@ public List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class
return doMultiSearch(multiSearchQueryParameters);
}

@Override
public List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class<?>> classes,
List<IndexCoordinates> indexes) {

Assert.notNull(queries, "queries must not be null");
Assert.notNull(classes, "classes must not be null");
Assert.notNull(indexes, "indexes must not be null");
Assert.isTrue(queries.size() == classes.size() && queries.size() == indexes.size(),
"queries, classes and indexes must have the same size");

List<MultiSearchQueryParameter> multiSearchQueryParameters = new ArrayList<>(queries.size());
Iterator<Class<?>> it = classes.iterator();
Iterator<IndexCoordinates> indexesIt = indexes.iterator();

for (Query query : queries) {
Class<?> clazz = it.next();
IndexCoordinates index = indexesIt.next();
multiSearchQueryParameters.add(new MultiSearchQueryParameter(query, clazz, index));
}

return doMultiSearch(multiSearchQueryParameters);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private List<SearchHits<?>> doMultiSearch(List<MultiSearchQueryParameter> multiSearchQueryParameters) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
* @author Massimiliano Poggi
* @author Farid Faoudi
* @author Sijia Liu
* @author Hamid Rahimi
* @since 4.4
* @deprecated since 5.0
*/
Expand Down Expand Up @@ -549,6 +550,42 @@ public List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class
return res;
}

@Override
public List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class<?>> classes,
List<IndexCoordinates> indexes) {

Assert.notNull(queries, "queries must not be null");
Assert.notNull(classes, "classes must not be null");
Assert.notNull(indexes, "indexes must not be null");
Assert.isTrue(queries.size() == classes.size() && queries.size() == indexes.size(),
"queries, classes and indexes must have the same size");

MultiSearchRequest request = new MultiSearchRequest();
Iterator<Class<?>> it = classes.iterator();
Iterator<IndexCoordinates> indexesIt = indexes.iterator();
for (Query query : queries) {
request.add(requestFactory.searchRequest(query, it.next(), indexesIt.next()));
}

MultiSearchResponse.Item[] items = getMultiSearchResult(request);

List<SearchHits<?>> res = new ArrayList<>(queries.size());
Iterator<Class<?>> it1 = classes.iterator();
Iterator<IndexCoordinates> indexesIt1 = indexes.iterator();
for (int i = 0; i < queries.size(); i++) {
Class entityClass = it1.next();
IndexCoordinates index = indexesIt1.next();

ReadDocumentCallback<?> documentCallback = new ReadDocumentCallback<>(elasticsearchConverter, entityClass, index);
SearchDocumentResponseCallback<SearchHits<?>> callback = new ReadSearchDocumentResponseCallback<>(entityClass,
index);

SearchResponse response = items[i].getResponse();
res.add(callback.doWith(SearchDocumentResponseBuilder.from(response, getEntityCreator(documentCallback))));
}
return res;
}

protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) {
MultiSearchResponse response = execute(client -> client.msearch(request, RequestOptions.DEFAULT));
MultiSearchResponse.Item[] items = response.getResponses();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*
* @author Peter-Josef Meisch
* @author Sascha Woo
* @author Hamid Rahimi
* @since 4.0
*/
public interface SearchOperations {
Expand Down Expand Up @@ -127,11 +128,21 @@ default <T> SearchHit<T> searchOne(Query query, Class<T> clazz, IndexCoordinates
*
* @param queries the queries to execute
* @param classes the entity classes used for property mapping
* @param index the index to run the query against
* @param index the index to run the queries against
* @return list of SearchHits
*/
List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class<?>> classes, IndexCoordinates index);

/**
* Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}.
*
* @param queries the queries to execute
* @param classes the entity classes used for property mapping
* @param indexes the indexes to run the queries against
* @return list of SearchHits
*/
List<SearchHits<?>> multiSearch(List<? extends Query> queries, List<Class<?>> classes, List<IndexCoordinates> indexes);

/**
* Execute the criteria query against elasticsearch and return result as {@link SearchHits}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
* @author Sijia Liu
* @author Haibo Liu
* @author scoobyzhang
* @author Hamid Rahimi
*/
@SpringIntegrationTest
public abstract class ElasticsearchIntegrationTests {
Expand Down Expand Up @@ -1769,6 +1770,40 @@ public void shouldReturnDifferentEntityForMultiSearch() {
assertThat(searchHit1.getContent().getClass()).isEqualTo(Book.class);
}

@Test // #2434
public void shouldReturnDifferentEntityForMultiSearchWithMultipleIndexCoordinates() {

IndexOperations bookIndexOperations = operations.indexOps(Book.class);
bookIndexOperations.delete();
bookIndexOperations.createWithMapping();
bookIndexOperations.refresh();
IndexCoordinates bookIndex = IndexCoordinates.of("i-need-my-own-index");
operations.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()),
IndexCoordinates.of(indexNameProvider.indexName()));
operations.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex);
bookIndexOperations.refresh();

List<Query> queries = new ArrayList<>();
queries.add(getTermQuery("message", "ab"));
queries.add(getTermQuery("description", "bc"));

List<SearchHits<?>> searchHitsList = operations.multiSearch(queries,
Lists.newArrayList(SampleEntity.class, Book.class),
List.of(IndexCoordinates.of(indexNameProvider.indexName()),
IndexCoordinates.of(bookIndex.getIndexName())));

bookIndexOperations.delete();

SearchHits<?> searchHits0 = searchHitsList.get(0);
assertThat(searchHits0.getTotalHits()).isEqualTo(1L);
SearchHit<SampleEntity> searchHit0 = (SearchHit<SampleEntity>) searchHits0.getSearchHit(0);
assertThat(searchHit0.getContent().getClass()).isEqualTo(SampleEntity.class);
SearchHits<?> searchHits1 = searchHitsList.get(1);
assertThat(searchHits1.getTotalHits()).isEqualTo(1L);
SearchHit<Book> searchHit1 = (SearchHit<Book>) searchHits1.getSearchHit(0);
assertThat(searchHit1.getContent().getClass()).isEqualTo(Book.class);
}

@Test
public void shouldIndexDocumentForSpecifiedSource() {

Expand Down