Home > database >  Spring Data ElasticSearch (7.9.3) add field to existed index
Spring Data ElasticSearch (7.9.3) add field to existed index

Time:12-02

I trying to add a new field (bioAuto) to existed index (users). I have POJO for this index:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.Setting;

import java.time.LocalDateTime;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = IndexName.USERS)
@Setting(settingPath = "elastic/autocomplete_settings.json")
public class User {

    @Id
    private Long id;

    @Field(type = FieldType.Search_As_You_Type)
    private String userName;

    @Field(type = FieldType.Text, analyzer = "autocomplete_whitespace_only", searchAnalyzer = "autocomplete_search")
    private String bioAuto;

}

Field created, but type is wrong, it doesn't connected with my custom analyzers (defined in elastic/autocomplete_settings.json).

Created field type:

"bioAuto" : {
      "type" : "text",
      "fields" : {
        "keyword" : {
          "type" : "keyword",
          "ignore_above" : 256
        }
      }
    }

Right field type:

"bioAuto" : {
      "type" : "text",
      "analyzer" : "autocomplete_whitespace_only",
      "search_analyzer" : "autocomplete_search"
    },

If I re-create my index (remove users index and run the application one more time), everything works fine. ElasticCloud: 7.9.3, Spring Data version: 4.2.6

P.S. If I execute this command, everything also works fine, the problem in automatic field creation with right type in Spring Data Elastic

PUT /users/_mapping
{
"properties": {
    "bioAuto" : {
          "type" : "text",
          "analyzer" : "autocomplete_whitespace_only",
          "search_analyzer" : "autocomplete_search"
        }
  }
}

CodePudding user response:

Spring Data Elasticsearch only automatically writes a mapping for an index when on application startup an ElasticsearchRepository with an entity for that index finds that the index does not exist. Otherwise nothing is done automatically on an index. The mapping is not rewritten. So if you add some property to your entity even though you have the annotations on it, this does not create a new mapping.

What you can do is - after adding the property and before inserting new data with this new property - use the IndexOperations.putMapping() method to write an updated mapping. Important: you can only add new properties/fields to an index not delete or update existing ones; this is a restriction from Elasticsearch.

To see how this might be done automatically on application startup see my answer to this SO question: Spring Data Elasticsearch : detect mapping differences

  • Related