diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 201e02258..936f0acaf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -128,6 +128,9 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery } else if (tree.isCountProjection()) { result = elasticsearchOperations.count(query, clazz, index); + } else if (tree.isExistsProjection()) { + long count = elasticsearchOperations.count(query, clazz, index); + result = count > 0; } else { result = elasticsearchOperations.searchOne(query, clazz, index); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index 7da426757..819f8adc2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -321,6 +321,17 @@ class QueryKeywordsTests { assertThat(searchHits.getTotalHits()).isEqualTo(5); } + @Test // #2162 + @DisplayName("should run exists query") + void shouldRunExistsQuery() { + + Boolean existsCaneSugar = repository.existsByText("Cane sugar"); + Boolean existsSand = repository.existsByText("Sand"); + + assertThat(existsCaneSugar).isTrue(); + assertThat(existsSand).isFalse(); + } + @SuppressWarnings("unused") @Document(indexName = "test-index-product-query-keywords") static class Product { @@ -459,6 +470,8 @@ class QueryKeywordsTests { SearchHits findByNameEmpty(); SearchHits findByNameNotEmpty(); + + Boolean existsByText(String text); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java index dc0f7a1ff..ae4939628 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/ReactiveQueryKeywordsIntegrationTests.java @@ -19,8 +19,11 @@ import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.lang.Boolean; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Order; @@ -139,6 +142,21 @@ public class ReactiveQueryKeywordsIntegrationTests { }).verifyComplete(); } + @Test // #2162 + @DisplayName("should run exists query") + void shouldRunExistsQuery() { + + loadEntities(); + repository.existsByMessage("message") // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + repository.existsByMessage("without") // + .as(StepVerifier::create) // + .expectNext(false) // + .verifyComplete(); + } + @SuppressWarnings("SpringDataMethodInconsistencyInspection") interface SampleRepository extends ReactiveElasticsearchRepository { Flux> findByMessageExists(); @@ -150,6 +168,8 @@ public class ReactiveQueryKeywordsIntegrationTests { Flux> findByMessageIsNotEmpty(); Flux> findByMessageIsEmpty(); + + Mono existsByMessage(String message); } private void loadEntities() {