From 8686650261af5636a8e38459408324a01eb921c6 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 24 Aug 2020 07:02:43 +0200 Subject: [PATCH] DATAES-912 - Derived Query with "In" Keyword does not work on Text field. Original PR: #510 (cherry picked from commit 79fdc449b873b317cc6d9544285e870c11a4d240) --- .../elasticsearch-repository-queries.adoc | 17 +- .../core/CriteriaQueryProcessor.java | 52 ++++- .../MappingElasticsearchConverter.java | 13 +- .../data/elasticsearch/core/query/Field.java | 14 ++ .../elasticsearch/core/query/SimpleField.java | 27 ++- .../core/ElasticsearchPartQueryTests.java | 48 ++-- .../CustomMethodRepositoryBaseTests.java | 220 +++++++++++------- .../data/elasticsearch/utils/IdGenerator.java | 41 ++++ 8 files changed, 313 insertions(+), 119 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index c17844fb3..7b35a79a0 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -48,7 +48,9 @@ A list of supported keywords for Elasticsearch is shown below. |=== | Keyword | Sample -| Elasticsearch Query String| `And` +| Elasticsearch Query String + +| `And` | `findByNameAndPrice` | `{ "query" : { "bool" : { @@ -201,7 +203,7 @@ A list of supported keywords for Elasticsearch is shown below. } }}` -| `In` +| `In` (when annotated as FieldType.Keyword) | `findByNameIn(Collectionnames)` | `{ "query" : { "bool" : { @@ -215,7 +217,12 @@ A list of supported keywords for Elasticsearch is shown below. } }}` -| `NotIn` + +| `In` +| `findByNameIn(Collectionnames)` +| `{ "query": {"bool": {"must": [{"query_string":{"query": "\"?\" \"?\"", "fields": ["name"]}}]}}}` + +| `NotIn` (when annotated as FieldType.Keyword) | `findByNameNotIn(Collectionnames)` | `{ "query" : { "bool" : { @@ -229,6 +236,10 @@ A list of supported keywords for Elasticsearch is shown below. } }}` +| `NotIn` +| `findByNameNotIn(Collectionnames)` +| `{"query": {"bool": {"must": [{"query_string": {"query": "NOT(\"?\" \"?\")", "fields": ["name"]}}]}}}` + | `Near` | `findByStoreNear` | `Not Supported Yet !` diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java index a1f9c919c..9b70b263f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java @@ -29,7 +29,9 @@ import org.apache.lucene.queryparser.flexible.core.util.StringUtils; import org.apache.lucene.queryparser.flexible.standard.QueryParserUtil; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.Field; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -118,18 +120,19 @@ class CriteriaQueryProcessor { Iterator it = chainedCriteria.getQueryCriteriaEntries().iterator(); boolean singeEntryCriteria = (chainedCriteria.getQueryCriteriaEntries().size() == 1); - String fieldName = chainedCriteria.getField().getName(); + Field field = chainedCriteria.getField(); + String fieldName = field.getName(); Assert.notNull(fieldName, "Unknown field"); QueryBuilder query = null; if (singeEntryCriteria) { Criteria.CriteriaEntry entry = it.next(); - query = processCriteriaEntry(entry, fieldName); + query = processCriteriaEntry(entry, field); } else { query = boolQuery(); while (it.hasNext()) { Criteria.CriteriaEntry entry = it.next(); - ((BoolQueryBuilder) query).must(processCriteriaEntry(entry, fieldName)); + ((BoolQueryBuilder) query).must(processCriteriaEntry(entry, field)); } } @@ -138,7 +141,11 @@ class CriteriaQueryProcessor { } @Nullable - private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String fieldName) { + private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, Field field) { + + String fieldName = field.getName(); + boolean isKeywordField = FieldType.Keyword == field.getFieldType(); + OperationKey key = entry.getKey(); Object value = entry.getValue(); @@ -191,10 +198,24 @@ class CriteriaQueryProcessor { query = fuzzyQuery(fieldName, searchText); break; case IN: - query = boolQuery().must(termsQuery(fieldName, toStringList((Iterable) value))); + if (value instanceof Iterable) { + Iterable iterable = (Iterable) value; + if (isKeywordField) { + query = boolQuery().must(termsQuery(fieldName, toStringList(iterable))); + } else { + query = queryStringQuery(orQueryString(iterable)).field(fieldName); + } + } break; case NOT_IN: - query = boolQuery().mustNot(termsQuery(fieldName, toStringList((Iterable) value))); + if (value instanceof Iterable) { + Iterable iterable = (Iterable) value; + if (isKeywordField) { + query = boolQuery().mustNot(termsQuery(fieldName, toStringList(iterable))); + } else { + query = queryStringQuery("NOT(" + orQueryString(iterable) + ')').field(fieldName); + } + } break; } return query; @@ -208,6 +229,25 @@ class CriteriaQueryProcessor { return list; } + private static String orQueryString(Iterable iterable) { + StringBuilder sb = new StringBuilder(); + + for (Object item : iterable) { + + if (item != null) { + + if (sb.length() > 0) { + sb.append(' '); + } + sb.append('"'); + sb.append(QueryParserUtil.escape(item.toString())); + sb.append('"'); + } + } + + return sb.toString(); + } + private void addBoost(QueryBuilder query, float boost) { if (Float.isNaN(boost)) { return; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 0cea748ef..43ff7a2c4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -48,6 +48,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersiste import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.Field; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; @@ -753,11 +754,12 @@ public class MappingElasticsearchConverter if (persistentEntity != null) { criteriaQuery.getCriteria().getCriteriaChain().forEach(criteria -> { - String name = criteria.getField().getName(); + Field field = criteria.getField(); + String name = field.getName(); ElasticsearchPersistentProperty property = persistentEntity.getPersistentProperty(name); if (property != null && property.getName().equals(name)) { - criteria.getField().setName(property.getFieldName()); + field.setName(property.getFieldName()); if (property.hasPropertyConverter()) { ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); @@ -773,6 +775,13 @@ public class MappingElasticsearchConverter } }); } + + org.springframework.data.elasticsearch.annotations.Field fieldAnnotation = property.findAnnotation(org.springframework.data.elasticsearch.annotations.Field.class); + + if (fieldAnnotation != null) { + field.setFieldType(fieldAnnotation.type()); + } + } }); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java index aa80c12dc..92969a11d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java @@ -15,6 +15,9 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.lang.Nullable; + /** * Defines a Field that can be used within a Criteria. * @@ -27,4 +30,15 @@ public interface Field { void setName(String name); String getName(); + + /** + * @param fieldType sets the field's type + */ + void setFieldType(FieldType fieldType); + + /** + * @return The annotated FieldType of the field + */ + @Nullable + FieldType getFieldType(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index bf4503492..1091bdb78 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -15,10 +15,13 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * The most trivial implementation of a Field + * The most trivial implementation of a Field. The {@link #name} is updatable, so it may be changed during query + * preparation by the {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. * * @author Rizwan Idrees * @author Mohsin Husen @@ -27,27 +30,41 @@ import org.springframework.util.Assert; public class SimpleField implements Field { private String name; + @Nullable private FieldType fieldType; public SimpleField(String name) { - Assert.notNull(name, "name must not be null"); + + Assert.hasText(name, "name must not be null"); this.name = name; } @Override public void setName(String name) { - Assert.notNull(name, "name must not be null"); + + Assert.hasText(name, "name must not be null"); this.name = name; } @Override public String getName() { - return this.name; + return name; + } + + @Override + public void setFieldType(FieldType fieldType) { + this.fieldType = fieldType; + } + + @Nullable + @Override + public FieldType getFieldType() { + return fieldType; } @Override public String toString() { - return this.name; + return getName(); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java index 8382cdc20..4dd579597 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -197,14 +197,22 @@ class ElasticsearchPartQueryTests { String query = getQueryBuilder(methodName, parameterClasses, parameters); - String expected = "{\"query\": {" + // - " \"bool\" : {" + // - " \"must\" : [" + // - " {\"bool\" : {\"must\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) - + "\"]}}]}}" + // - " ]" + // - " }" + // - "}}"; // + String expected = "{\n" + // + " \"query\": {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"\\\"Title\\\" \\\"Title2\\\"\",\n" + // + " \"fields\": [\n" + // + " \"name^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + "}\n"; // assertEquals(expected, query, false); } @@ -220,14 +228,22 @@ class ElasticsearchPartQueryTests { String query = getQueryBuilder(methodName, parameterClasses, parameters); - String expected = "{\"query\": {" + // - " \"bool\" : {" + // - " \"must\" : [" + // - " {\"bool\" : {\"must_not\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) - + "\"]}}]}}" + // - " ]" + // - " }" + // - "}}"; // + String expected = "{\n" + // + " \"query\": {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"NOT(\\\"Title\\\" \\\"Title2\\\")\",\n" + // + " \"fields\": [\n" + // + " \"name^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + "}\n"; // assertEquals(expected, query, false); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 34e5e9726..780626d78 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -100,7 +100,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethod() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -119,7 +119,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForNot() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("some"); @@ -137,7 +137,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -157,7 +157,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithLessThan() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -165,7 +165,7 @@ public abstract class CustomMethodRepositoryBaseTests { sampleEntity.setMessage("some message"); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -185,7 +185,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithBefore() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -205,7 +205,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithAfter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -225,7 +225,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithLike() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -245,7 +245,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForStartingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -265,7 +265,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForEndingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -285,7 +285,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForContains() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -305,7 +305,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -313,7 +313,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -334,7 +334,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForNotIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -342,7 +342,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -360,16 +360,16 @@ public abstract class CustomMethodRepositoryBaseTests { } @Test // DATAES-647 - public void shouldHandleManyValuesQueryingIn() { + public void shouldHandleManyKeywordValuesQueryingIn() { // given - String documentId1 = randomNumeric(32); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setKeyword("foo"); repository.save(sampleEntity1); - String documentId2 = randomNumeric(32); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setKeyword("bar"); @@ -378,8 +378,9 @@ public abstract class CustomMethodRepositoryBaseTests { List keywords = new ArrayList<>(); keywords.add("foo"); - for (int i = 0; i < 1025; i++) { - keywords.add(randomNumeric(32)); + // limit for normal query clauses is 1024, for keywords we change to terms queries + for (int i = 0; i < 1200; i++) { + keywords.add(nextIdAsString()); } // when @@ -391,16 +392,16 @@ public abstract class CustomMethodRepositoryBaseTests { } @Test // DATAES-647 - public void shouldHandleManyValuesQueryingNotIn() { + public void shouldHandleManyKeywordValuesQueryingNotIn() { // given - String documentId1 = randomNumeric(32); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setKeyword("foo"); repository.save(sampleEntity1); - String documentId2 = randomNumeric(32); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setKeyword("bar"); @@ -409,8 +410,9 @@ public abstract class CustomMethodRepositoryBaseTests { List keywords = new ArrayList<>(); keywords.add("foo"); - for (int i = 0; i < 1025; i++) { - keywords.add(randomNumeric(32)); + // limit for normal query clauses is 1024, for keywords we change to terms queries + for (int i = 0; i < 1200; i++) { + keywords.add(nextIdAsString()); } // when @@ -421,11 +423,51 @@ public abstract class CustomMethodRepositoryBaseTests { assertThat(list.get(0).getId()).isEqualTo(documentId2); } + @Test // DATAES-912 + void shouldHandleTextFieldQueryingIn() { + String documentId1 = nextIdAsString(); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId1); + sampleEntity1.setMessage("foo"); + repository.save(sampleEntity1); + + String documentId2 = nextIdAsString(); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setMessage("bar"); + repository.save(sampleEntity2); + + List list = repository.findByMessageIn(Arrays.asList("Foo", "Bar")); + + assertThat(list).hasSize(2); + assertThat(list.stream().map(SampleEntity::getId)).containsExactlyInAnyOrder(documentId1, documentId2); + } + + @Test // DATAES-912 + void shouldHandleTextFieldQueryingNotIn() { + String documentId1 = nextIdAsString(); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId1); + sampleEntity1.setMessage("foo"); + repository.save(sampleEntity1); + + String documentId2 = nextIdAsString(); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setMessage("bar"); + repository.save(sampleEntity2); + + List list = repository.findByMessageNotIn(Arrays.asList("Boo", "Bar")); + + assertThat(list).hasSize(1); + assertThat(list.get(0).getId()).isEqualTo(documentId1); + } + @Test public void shouldExecuteCustomMethodForTrue() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -434,7 +476,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -453,7 +495,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForFalse() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -462,7 +504,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -482,7 +524,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodForOrderBy() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("abc"); @@ -491,7 +533,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // document 2 - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("xyz"); @@ -500,7 +542,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity2); // document 3 - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setType("def"); @@ -520,7 +562,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithBooleanParameter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -529,7 +571,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -549,7 +591,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldReturnPageableInUnwrappedPageResult() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -558,7 +600,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -601,21 +643,21 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldReturnPageableResultsWithGivenSortingOrder() { // given - String documentId = random(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("abc"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("abd"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity2); - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setMessage("abe"); @@ -635,21 +677,21 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldReturnListForMessage() { // given - String documentId = random(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("abc"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("abd"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity2); - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setMessage("abe"); @@ -667,7 +709,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -689,7 +731,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithGeoPointAndString() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -699,7 +741,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -722,7 +764,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithWithinGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -745,7 +787,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithWithinPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -768,7 +810,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithNearBox() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -778,7 +820,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -808,7 +850,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldExecuteCustomMethodWithNearPointAndDistance() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -846,7 +888,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethod() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -854,7 +896,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -873,7 +915,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForNot() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("some"); @@ -881,7 +923,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -900,7 +942,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithBooleanParameter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -909,7 +951,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -928,7 +970,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithLessThan() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -936,7 +978,7 @@ public abstract class CustomMethodRepositoryBaseTests { sampleEntity.setMessage("some message"); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -955,7 +997,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithBefore() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -964,7 +1006,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -984,7 +1026,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithAfter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -993,7 +1035,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1013,7 +1055,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithLike() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1022,7 +1064,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1042,7 +1084,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForStartingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1051,7 +1093,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1071,7 +1113,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForEndingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1080,7 +1122,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1100,7 +1142,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForContains() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1109,7 +1151,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1129,7 +1171,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1137,7 +1179,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1157,7 +1199,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForNotIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1165,7 +1207,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1185,7 +1227,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForTrue() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1194,7 +1236,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1212,7 +1254,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodForFalse() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1221,7 +1263,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1240,7 +1282,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithWithinGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1250,7 +1292,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1271,7 +1313,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithWithinPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1281,7 +1323,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1302,7 +1344,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithNearBox() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1312,7 +1354,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -1333,7 +1375,7 @@ public abstract class CustomMethodRepositoryBaseTests { public void shouldCountCustomMethodWithNearPointAndDistance() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1343,7 +1385,7 @@ public abstract class CustomMethodRepositoryBaseTests { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1622,6 +1664,10 @@ public abstract class CustomMethodRepositoryBaseTests { List findByKeywordNotIn(List keywords); + List findByMessageIn(List keywords); + + List findByMessageNotIn(List keywords); + Page findByIdNotIn(List ids, Pageable pageable); Page findByAvailableTrue(Pageable pageable); diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java b/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java new file mode 100644 index 000000000..9ea7770f2 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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.utils; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Class to provide sequential IDs. Uses an integer, 2^31 -1 values should be enough for the test runs. + * + * @author Peter-Josef Meisch + */ +public final class IdGenerator { + + private static final AtomicInteger NEXT = new AtomicInteger(); + + private IdGenerator() {} + + public static int nextIdAsInt() { + return NEXT.incrementAndGet(); + } + + public static double nextIdAsDouble() { + return NEXT.incrementAndGet(); + } + public static String nextIdAsString() { + return "" + nextIdAsInt(); + } +}