Allow field names with dots.

Original Pull Request #2504
Closes #2502
This commit is contained in:
Peter-Josef Meisch 2023-03-22 19:51:00 +01:00 committed by GitHub
parent d95af9fcfa
commit 675b77982b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 4 deletions

View File

@ -1419,7 +1419,7 @@ public class MappingElasticsearchConverter
}
if (!fieldName.contains(".")) {
if (property.hasExplicitFieldName() || !fieldName.contains(".")) {
return target.get(fieldName);
}

View File

@ -39,6 +39,12 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
*/
String getFieldName();
/**
* @return {@literal true} if the field name comes from an explicit value in the field annotation
* @since 5.1
*/
boolean hasExplicitFieldName();
/**
* Returns whether the current property is a {@link SeqNoPrimaryTerm} property.
*

View File

@ -142,7 +142,8 @@ public class SimpleElasticsearchPersistentProperty extends
return storeEmptyValue;
}
protected boolean hasExplicitFieldName() {
@Override
public boolean hasExplicitFieldName() {
return StringUtils.hasText(getAnnotatedFieldName());
}

View File

@ -1947,6 +1947,48 @@ public class MappingElasticsearchConverterUnitTests {
assertEquals(expected, json, true);
}
@Test // #2502
@DisplayName("should write entity with dotted field name")
void shouldWriteEntityWithDottedFieldName() throws JSONException {
@Language("JSON")
var expected = """
{
"_class": "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$FieldNameDotsEntity",
"id": "42",
"dotted.field": "dotted field"
}
""";
var entity = new FieldNameDotsEntity();
entity.setId("42");
entity.setDottedField("dotted field");
Document document = Document.create();
mappingElasticsearchConverter.write(entity, document);
String json = document.toJson();
assertEquals(expected, json, true);
}
@Test // #2502
@DisplayName("should read entity with dotted field name")
void shouldReadEntityWithDottedFieldName() {
@Language("JSON")
String json = """
{
"id": "42",
"dotted.field": "dotted field"
}""";
Document document = Document.parse(json);
FieldNameDotsEntity entity = mappingElasticsearchConverter.read(FieldNameDotsEntity.class, document);
assertThat(entity.id).isEqualTo("42");
assertThat(entity.getDottedField()).isEqualTo("dotted field");
}
// region entities
public static class Sample {
@Nullable public @ReadOnlyProperty String readOnly;
@ -3150,6 +3192,31 @@ public class MappingElasticsearchConverterUnitTests {
this.mapToNotWriteWhenEmpty = mapToNotWriteWhenEmpty;
}
}
static class FieldNameDotsEntity {
@Id
@Nullable private String id;
@Nullable
@Field(name = "dotted.field", type = FieldType.Text) private String dottedField;
@Nullable
public String getId() {
return id;
}
public void setId(@Nullable String id) {
this.id = id;
}
@Nullable
public String getDottedField() {
return dottedField;
}
public void setDottedField(@Nullable String dottedField) {
this.dottedField = dottedField;
}
}
// endregion
private static String reverse(Object o) {

View File

@ -279,6 +279,14 @@ public abstract class MappingBuilderIntegrationTests extends MappingContextBaseT
indexOps.createWithMapping();
}
@Test // #2502
@DisplayName(" should write mapping with field name with dots")
void shouldWriteMappingWithFieldNameWithDots() {
IndexOperations indexOps = operations.indexOps(FieldNameDotsEntity.class);
indexOps.createWithMapping();
}
// region Entities
@Document(indexName = "#{@indexNameProvider.indexName()}")
static class Book {
@ -901,5 +909,12 @@ public abstract class MappingBuilderIntegrationTests extends MappingContextBaseT
@Nullable
@Field(type = FieldType.Dense_Vector, dims = 1) String denseVectorField;
}
@Document(indexName = "#{@indexNameProvider.indexName()}")
private static class FieldNameDotsEntity {
@Id
@Nullable private String id;
@Nullable
@Field(name = "dotted.field", type = Text) private String dottedField;
}
// endregion
}

View File

@ -1065,6 +1065,30 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
assertEquals(expected, mapping, true);
}
@Test // #2502
@DisplayName("should use custom name with dots")
void shouldUseCustomNameWithDots() throws JSONException {
var expected = """
{
"properties": {
"_class": {
"type": "keyword",
"index": false,
"doc_values": false
},
"dotted.field": {
"type": "text"
}
}
}
""";
String mapping = getMappingBuilder().buildPropertyMapping(FieldNameDotsEntity.class);
assertEquals(expected, mapping, true);
}
// region entities
@Document(indexName = "ignore-above-index")
@ -2220,8 +2244,14 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
@Nullable
@Field(type = Text) private String someText;
@Nullable
@IndexedIndexName
private String storedIndexName;
@IndexedIndexName private String storedIndexName;
}
private static class FieldNameDotsEntity {
@Id
@Nullable private String id;
@Nullable
@Field(name = "dotted.field", type = Text) private String dottedField;
}
// endregion
}