From 03e02b333dbdbc9c37693cee5b8af599821a27f0 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 6 Apr 2021 20:48:30 +0200 Subject: [PATCH] CriteriaQuery must use nested query only with properties of type nested. --- .../MappingElasticsearchConverter.java | 13 ++++++- .../core/CriteriaQueryMappingUnitTests.java | 35 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) 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 1f3dc30d1..18286bb1c 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 @@ -33,6 +33,7 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.convert.CustomConversions; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; @@ -1055,12 +1056,22 @@ private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity ElasticsearchPersistentEntity currentEntity = persistentEntity; ElasticsearchPersistentProperty persistentProperty = null; int propertyCount = 0; + boolean isNested = false; + for (int i = 0; i < fieldNames.length; i++) { persistentProperty = currentEntity.getPersistentProperty(fieldNames[i]); if (persistentProperty != null) { propertyCount++; fieldNames[i] = persistentProperty.getFieldName(); + + org.springframework.data.elasticsearch.annotations.Field fieldAnnotation = persistentProperty + .findAnnotation(org.springframework.data.elasticsearch.annotations.Field.class); + + if (fieldAnnotation != null && fieldAnnotation.type() == FieldType.Nested) { + isNested = true; + } + try { currentEntity = mappingContext.getPersistentEntity(persistentProperty.getActualType()); } catch (Exception e) { @@ -1077,7 +1088,7 @@ private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity field.setName(String.join(".", fieldNames)); - if (propertyCount > 1) { + if (propertyCount > 1 && isNested) { List propertyNames = Arrays.asList(fieldNames); field.setPath(String.join(".", propertyNames.subList(0, propertyCount - 1))); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingUnitTests.java index 10f2344b6..a54ae7b63 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingUnitTests.java @@ -397,6 +397,34 @@ void shouldMapNamesAndValueInNestedEntitiesWithSubfields() throws JSONException assertEquals(expected, queryString, false); } + + @Test // #1761 + @DisplayName("should map names and value in object entities") + void shouldMapNamesAndValueInObjectEntities() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"03.10.1999\",\n" + // + " \"fields\": [\n" + // + " \"per-sons.birth-date^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}\n"; // + + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("persons.birthDate").is(LocalDate.of(1999, 10, 3)) + ); + mappingElasticsearchConverter.updateQuery(criteriaQuery, ObjectWithPerson.class); + String queryString = new CriteriaQueryProcessor().createQuery(criteriaQuery.getCriteria()).toString(); + + assertEquals(expected, queryString, false); + } // endregion // region helper functions @@ -427,6 +455,13 @@ static class House { List persons; } + static class ObjectWithPerson { + @Nullable @Id String id; + @Nullable + @Field(name = "per-sons", type = FieldType.Object) + List persons; + } + static class GeoShapeEntity { @Nullable @Field(name = "geo-shape-field") GeoJson geoShapeField; }