diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index a6c56f70b..34507b56f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -82,8 +82,7 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor ResultProcessor processor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor); - Query query = createQuery( - new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor)); + Query query = createQuery(parameterAccessor); if (queryMethod.hasAnnotatedHighlight()) { query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery()); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java deleted file mode 100644 index 9d7255562..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.elasticsearch.repository.query; - -import java.util.Iterator; -import java.util.Optional; - -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; -import org.springframework.lang.Nullable; - -/** - * @author Christoph Strobl - * @author Peter-Josef Meisch - * @since 3.2 - */ -public class ConvertingParameterAccessor implements ElasticsearchParameterAccessor { - - private final ElasticsearchConverter converter; - private final ElasticsearchParameterAccessor delegate; - - public ConvertingParameterAccessor(ElasticsearchConverter converter, ElasticsearchParameterAccessor delegate) { - - this.converter = converter; - this.delegate = delegate; - } - - @Override - public Object[] getValues() { - return delegate.getValues(); - } - - @Override - public Pageable getPageable() { - return delegate.getPageable(); - } - - @Override - public Sort getSort() { - return delegate.getSort(); - } - - @Override - public Optional> getDynamicProjection() { - return delegate.getDynamicProjection(); - } - - @Override - public Class findDynamicProjection() { - return delegate.findDynamicProjection(); - } - - @Override - public Object getBindableValue(int index) { - return getConvertedValue(delegate.getBindableValue(index)); - } - - @Override - public boolean hasBindableNullValue() { - return delegate.hasBindableNullValue(); - } - - @Override - public Iterator iterator() { - return delegate.iterator(); - } - - @Nullable - private Object getConvertedValue(Object value) { - - if (value == null) { - return "null"; - } - - if (converter.getConversionService().canConvert(value.getClass(), String.class)) { - return converter.getConversionService().convert(value, String.class); - } - - return value.toString(); - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java index aabbd80f7..d88596c7f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 the original author or authors. + * Copyright 2019-2022 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. @@ -144,10 +144,37 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri .isEqualTo("{ 'bool' : { 'must' : { 'term' : { 'car' : 'Toyota-Prius' } } } }"); } + @Test // #2135 + @DisplayName("should handle array-of-strings parameters correctly") + void shouldHandleArrayOfStringsParametersCorrectly() throws Exception { + + List otherNames = Arrays.asList("Wesley", "Emmett"); + + org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByOtherNames", otherNames); + + assertThat(query).isInstanceOf(StringQuery.class); + assertThat(((StringQuery) query).getSource()) + .isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : [\"Wesley\",\"Emmett\"] } } } }"); + } + + @Test // #2135 + @DisplayName("should handle array-of-Integers parameters correctly") + void shouldHandleArrayOfIntegerParametersCorrectly() throws Exception { + + List ages = Arrays.asList(42, 57); + + org.springframework.data.elasticsearch.core.query.Query query = createQuery("findByAges", ages); + + assertThat(query).isInstanceOf(StringQuery.class); + assertThat(((StringQuery) query).getSource()) + .isEqualTo("{ 'bool' : { 'must' : { 'terms' : { 'ages' : [42,57] } } } }"); + } + private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, Object... args) throws NoSuchMethodException { - Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new); + Class[] argTypes = Arrays.stream(args).map(Object::getClass) + .map(clazz -> Collection.class.isAssignableFrom(clazz) ? List.class : clazz).toArray(Class[]::new); ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes); ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod); @@ -195,6 +222,12 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri @Query("{ 'bool' : { 'must' : { 'term' : { 'car' : '?0' } } } }") Mono findByCar(Car car); + @Query("{ 'bool' : { 'must' : { 'terms' : { 'otherNames' : ?0 } } } }") + Flux findByOtherNames(List otherNames); + + @Query("{ 'bool' : { 'must' : { 'terms' : { 'ages' : ?0 } } } }") + Flux findByAges(List ages); + } /** @@ -206,10 +239,13 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri @Document(indexName = "test-index-person-reactive-repository-string-query") public class Person { - @Nullable @Id private String id; + @Nullable + @Id private String id; @Nullable private String name; + @Nullable private List otherNames; + @Nullable @Field(type = FieldType.Nested) private List car; @Nullable @Field(type = FieldType.Nested, includeInParent = true) private List books; @@ -232,6 +268,15 @@ public class ReactiveElasticsearchStringQueryUnitTests extends ElasticsearchStri this.name = name; } + @Nullable + public List getOtherNames() { + return otherNames; + } + + public void setOtherNames(List otherNames) { + this.otherNames = otherNames; + } + @Nullable public List getCar() { return car; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index bc0d1ed9c..330dc8c3f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.core.query.Query.*; +import org.springframework.data.elasticsearch.annotations.FieldType; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -91,7 +92,8 @@ class SimpleReactiveElasticsearchRepositoryTests { operations.indexOps(IndexCoordinates.of(INDEX)).delete().block(); } - @Test // DATAES-519 + @Test + // DATAES-519 void saveShouldSaveSingleEntity() { repository.save(new SampleEntity()) // @@ -105,7 +107,8 @@ class SimpleReactiveElasticsearchRepositoryTests { return operations.exists(id, IndexCoordinates.of(INDEX)); } - @Test // DATAES-519 + @Test + // DATAES-519 void saveShouldComputeMultipleEntities() { repository.saveAll(Arrays.asList(new SampleEntity(), new SampleEntity(), new SampleEntity())) @@ -118,46 +121,50 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519, DATAES-767, DATAES-822 + @Test + // DATAES-519, DATAES-767, DATAES-822 void findByIdShouldErrorIfIndexDoesNotExist() { repository.findById("id-two") // .as(StepVerifier::create) // .expectError(RestStatusException.class); } - @Test // DATAES-519 + @Test + // DATAES-519 void findShouldRetrieveSingleEntityById() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two"), // new SampleEntity("id-three")) // - .block(); + .block(); repository.findById("id-two").as(StepVerifier::create)// .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-two")) // .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void findByIdShouldCompleteIfNothingFound() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two"), // new SampleEntity("id-three")) // - .block(); + .block(); repository.findById("does-not-exist").as(StepVerifier::create) // .verifyComplete(); } - @Test // DATAES-720 + @Test + // DATAES-720 void findAllShouldReturnAllElements() { // make sure to be above the default page size of the Query interface int count = DEFAULT_PAGE_SIZE * 2; bulkIndex(IntStream.range(1, count + 1) // .mapToObj(it -> new SampleEntity(String.valueOf(it))) // .toArray(SampleEntity[]::new)) // - .block(); + .block(); repository.findAll() // .as(StepVerifier::create) // @@ -165,18 +172,20 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() { repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void findAllByIdShouldRetrieveMatchingDocuments() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two"), // new SampleEntity("id-three")) // - .block(); + .block(); repository.findAllById(Arrays.asList("id-one", "id-two")) // .as(StepVerifier::create)// @@ -185,26 +194,28 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void findAllByIdShouldCompleteWhenNothingFound() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two"), // new SampleEntity("id-three")) // - .block(); + .block(); repository.findAllById(Arrays.asList("can't", "touch", "this")) // .as(StepVerifier::create)// .verifyComplete(); } - @Test // DATAES-717 + @Test + // DATAES-717 void shouldReturnFluxOfSearchHit() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "message"), // new SampleEntity("id-three", "message")) // - .block(); + .block(); repository.queryAllByMessage("message") // .as(StepVerifier::create) // @@ -213,13 +224,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-717 + @Test + // DATAES-717 void shouldReturnFluxOfSearchHitForStringQuery() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "message"), // new SampleEntity("id-three", "message")) // - .block(); + .block(); repository.queryByMessageWithString("message") // .as(StepVerifier::create) // @@ -228,13 +240,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-372 + @Test + // DATAES-372 void shouldReturnHighlightsOnAnnotatedMethod() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "message"), // new SampleEntity("id-three", "message")) // - .block(); + .block(); repository.queryAllByMessage("message") // .as(StepVerifier::create) // @@ -246,13 +259,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-372 + @Test + // DATAES-372 void shouldReturnHighlightsOnAnnotatedStringQueryMethod() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "message"), // new SampleEntity("id-three", "message")) // - .block(); + .block(); repository.queryByMessageWithString("message") // .as(StepVerifier::create) // @@ -264,30 +278,33 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519, DATAES-767, DATAES-822 + @Test + // DATAES-519, DATAES-767, DATAES-822 void countShouldErrorWhenIndexDoesNotExist() { repository.count() // .as(StepVerifier::create) // .expectError(RestStatusException.class); } - @Test // DATAES-519 + @Test + // DATAES-519 void countShouldCountDocuments() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two")) // - .block(); + .block(); repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void existsByIdShouldReturnTrueIfExists() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.existsById("id-two") // .as(StepVerifier::create) // @@ -295,13 +312,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void existsByIdShouldReturnFalseIfNotExists() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.existsById("wrecking ball") // .as(StepVerifier::create) // @@ -309,7 +327,8 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void countShouldCountMatchingDocuments() { bulkIndex(new SampleEntity("id-one", "message"), // @@ -336,13 +355,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void existsShouldReturnTrueIfExists() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.existsAllByMessage("message") // .as(StepVerifier::create) // @@ -350,13 +370,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void existsShouldReturnFalseIfNotExists() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.existsAllByMessage("these days") // .as(StepVerifier::create) // @@ -364,24 +385,27 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void deleteByIdShouldCompleteIfNothingDeleted() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two")) // - .block(); + .block(); repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); } - @Test // DATAES-519, DATAES-767, DATAES-822, DATAES-678 + @Test + // DATAES-519, DATAES-767, DATAES-822, DATAES-678 void deleteByIdShouldCompleteWhenIndexDoesNotExist() { repository.deleteById("does-not-exist") // .as(StepVerifier::create) // .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void deleteByIdShouldDeleteEntry() { SampleEntity toBeDeleted = new SampleEntity("id-two"); @@ -393,19 +417,22 @@ class SimpleReactiveElasticsearchRepositoryTests { assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); } - @Test // DATAES-976 + @Test + // DATAES-976 void deleteAllByIdShouldDeleteEntry() { SampleEntity toBeDeleted = new SampleEntity("id-two"); bulkIndex(new SampleEntity("id-one"), toBeDeleted) // .block(); - repository.deleteAllById(Collections.singletonList(toBeDeleted.getId())).as(StepVerifier::create).verifyComplete(); + repository.deleteAllById(Collections.singletonList(toBeDeleted.getId())).as(StepVerifier::create) + .verifyComplete(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); } - @Test // DATAES-519 + @Test + // DATAES-519 void deleteShouldDeleteEntry() { SampleEntity toBeDeleted = new SampleEntity("id-two"); @@ -417,7 +444,8 @@ class SimpleReactiveElasticsearchRepositoryTests { assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); } - @Test // DATAES-519 + @Test + // DATAES-519 void deleteAllShouldDeleteGivenEntries() { SampleEntity toBeDeleted = new SampleEntity("id-one"); @@ -434,13 +462,14 @@ class SimpleReactiveElasticsearchRepositoryTests { assertThat(documentWithIdExistsInIndex(hangInThere.getId()).block()).isTrue(); } - @Test // DATAES-519 + @Test + // DATAES-519 void deleteAllShouldDeleteAllEntries() { bulkIndex(new SampleEntity("id-one"), // new SampleEntity("id-two"), // new SampleEntity("id-three")) // - .block(); + .block(); repository.deleteAll().as(StepVerifier::create).verifyComplete(); @@ -450,13 +479,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderMethodShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.findAllByMessageLike("test") // .as(StepVerifier::create) // @@ -464,13 +494,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.findAllByMessage(Mono.just("test")) // .as(StepVerifier::create) // @@ -478,13 +509,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "test", 3), // new SampleEntity("id-two", "test test", 1), // new SampleEntity("id-three", "test test", 2)) // - .block(); + .block(); repository.findAllByMessageLikeOrderByRate("test") // .as(StepVerifier::create) // @@ -494,13 +526,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "test", 3), // new SampleEntity("id-two", "test test", 1), // new SampleEntity("id-three", "test test", 2)) // - .block(); + .block(); repository.findAllByMessage("test", Sort.by(Order.asc("rate"))) // .as(StepVerifier::create) // @@ -510,13 +543,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "test", 3), // new SampleEntity("id-two", "test test", 1), // new SampleEntity("id-three", "test test", 2)) // - .block(); + .block(); repository.findAllByMessage("test", PageRequest.of(0, 2, Sort.by(Order.asc("rate")))) // .as(StepVerifier::create) // @@ -525,13 +559,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.findFirstByMessageLike("test") // .as(StepVerifier::create) // @@ -539,7 +574,8 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void annotatedFinderMethodShouldBeExecutedCorrectly() { int count = 30; @@ -555,7 +591,8 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // #1917 + @Test + // #1917 void annotatedFinderMethodPagedShouldBeExecutedCorrectly() { int count = 30; @@ -575,13 +612,14 @@ class SimpleReactiveElasticsearchRepositoryTests { .verifyComplete(); } - @Test // DATAES-519 + @Test + // DATAES-519 void derivedDeleteMethodShouldBeExecutedCorrectly() { bulkIndex(new SampleEntity("id-one", "message"), // new SampleEntity("id-two", "test message"), // new SampleEntity("id-three", "test test")) // - .block(); + .block(); repository.deleteAllByMessage("message") // .as(StepVerifier::create) // @@ -593,6 +631,56 @@ class SimpleReactiveElasticsearchRepositoryTests { assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue(); } + @Test + // #2135 + void FluxOfSearchHitForArrayQuery() { + bulkIndex(new SampleEntity("id-one", "message1"), // + new SampleEntity("id-two", "message2"), // + new SampleEntity("id-three", "message3")) // + .block(); + + repository.findAllViaAnnotatedQueryByMessageIn(Arrays.asList("message1", "message3")) // + .as(StepVerifier::create) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) // + .verifyComplete(); + + } + + @Test + // #2135 + void FluxOfSearchHitForIntegerArrayQuery() { + bulkIndex(new SampleEntity("id-one", "test", 3), // + new SampleEntity("id-two", "test test", 1), // + new SampleEntity("id-three", "test test", 2)) // + .block(); + + repository.findAllViaAnnotatedQueryByRatesIn(Arrays.asList(2, 3)) // + .as(StepVerifier::create) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-one")) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) // + .verifyComplete(); + + } + + @Test + // #2135 + void FluxOfSearchHitForStringAndIntegerArrayQuery() { + bulkIndex(new SampleEntity("id-one", "message1", 1), // + new SampleEntity("id-two", "message2", 2), // + new SampleEntity("id-three", "message3", 3), // + new SampleEntity("id-four", "message4", 4), // + new SampleEntity("id-five", "message5", 5)) // + .block(); + + repository.findAllViaAnnotatedQueryByMessageInAndRatesIn(Arrays.asList("message5", "message3"), Arrays.asList(2, + 3)) // + .as(StepVerifier::create) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-three")) // + .verifyComplete(); + + } + Mono bulkIndex(SampleEntity... entities) { return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then(); } @@ -609,11 +697,11 @@ class SimpleReactiveElasticsearchRepositoryTests { Flux findAllByMessage(Publisher message); - @Highlight(fields = { @HighlightField(name = "message") }) + @Highlight(fields = {@HighlightField(name = "message")}) Flux> queryAllByMessage(String message); @Query("{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}") - @Highlight(fields = { @HighlightField(name = "message") }) + @Highlight(fields = {@HighlightField(name = "message")}) Flux> queryByMessageWithString(String message); @Query("{ \"bool\" : { \"must\" : { \"term\" : { \"message\" : \"?0\" } } } }") @@ -632,18 +720,39 @@ class SimpleReactiveElasticsearchRepositoryTests { @CountQuery(value = "{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}") Mono retrieveCountByText(String message); + + @Query("{ \"terms\": { \"message\": ?0 } }") + Flux findAllViaAnnotatedQueryByMessageIn(List messages); + + @Query("{ \"terms\": { \"rate\": ?0 } }") + Flux findAllViaAnnotatedQueryByRatesIn(List rates); + + @Query("{\"bool\": {\"must\": [{ \"terms\": { \"message\": ?0 } }, { \"terms\": { \"rate\": ?1 } }] } }") + Flux findAllViaAnnotatedQueryByMessageInAndRatesIn(List messages, List rates); + } @Document(indexName = INDEX) static class SampleEntity { - @Nullable @Id private String id; - @Nullable @Field(type = Text, store = true, fielddata = true) private String type; - @Nullable @Field(type = Text, store = true, fielddata = true) private String message; - @Nullable private int rate; - @Nullable private boolean available; - @Nullable @Version private Long version; + @Nullable + @Id + private String id; + @Nullable + @Field(type = FieldType.Text, store = true, fielddata = true) + private String type; + @Nullable + @Field(type = FieldType.Text, store = true, fielddata = true) + private String message; + @Nullable + private int rate; + @Nullable + private boolean available; + @Nullable + @Version + private Long version; - public SampleEntity() {} + public SampleEntity() { + } public SampleEntity(@Nullable String id) { this.id = id;