I'm quite new to elastic search, I'm not able to set mapping via field annotation. I'm using spring data elastic 4.3.4. I'm adding settings via @Setting annotation which is actually working. But if I set Field type to Keyword it is not getting updated, and elastic dynamically maps the field type to text. My requirement is to add a normaliser to enable alphabetic sort on specific fields. Please find my set-up below, I really appreciate your help.
Configuration: Elastic Search version :"7.11.1", Spring data elastic 4.3.4.
Sample code
@Document(indexName = "#{@environment.getProperty('elastic.index.prefix')}-test")
@Setting(settingPath = "/elasticsearch/analyzer.json") public class ElasticTest {
@Id
String id;
@Field(type = FieldType.Keyword, normalizer="sort_normalizer")
private String name;
@Field
private String createdDate;
@Field(type=FieldType.Object)
private CustomerType customerType;
=============================================================================
So once the index is created, I can see the settings added
"creation_date" : "1664385255792",
"analysis" : {
"normalizer" : {
"sort_normalizer" : {
"filter" : [
"lowercase",
"asciifolding"
],
"type" : "custom",
"char_filter" : [ ]
}
},
"analyzer" : {
"custom_pattern_analyzer" : {
"lowercase" : "true",
"pattern" : """\W|_""",
"type" : "pattern"
}
}
},
Mapping:
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
Note: Since I'm working locally I have to drop and recreate the index multiple times. I'm able to set these field types via curl/kibana.
Update: Here we create the index by:
if (!searchTemplate.indexOps(ElasticContract.class).exists()) {
searchTemplate.indexOps(ElasticContract.class).create();
}
And we also use ElasticsearchRepository for querying.
CodePudding user response:
How are the index and the mapping created?
If you use Spring Data Elasticsearch repositories, then the index with the setting and mapping will be created if it does not yet exist on application startup.
If you do not use a repository, but use ElasticsearchOperations
, you will need to create the index by yourself:
ElasticsearchOperations operations;
IndexOperations indexOps = operations.indexOps(ElasticTest.class);
indexOps.createWithMapping();
If you do not create the index but just insert some data, then Elasticsearch will automatically create the index and the mapping. The mapping you show is the typical autocreated one for a String field.
The @Field
annotation you use is correct, we have a similar setup in one of the tests that tests exactly this behaviour, see https://github.com/spring-projects/spring-data-elasticsearch/blob/main/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java#L126-L145