Can we avoid mapping all the fields to entity class in springdata for elasticsearch, as I have more than 100 field in the json document?

早过忘川 提交于 2021-01-29 09:13:13

问题


I am implementing a spring-boot microservice for elasticsearch (es) operations using springdata APIs. My documents that are indexed in es are huge with multiple fields (more than 100).

Is there a way to avoid defining/hardcoding all the fields in the entity class for elasticsearch object in java?

My sample patient JSON could be like:

{
  "key_1":"value_1",
  "key_2":"value_2",
  "key_3":"value_3",
         .
         .
         .  

  "key_n":"value_n"
}


回答1:


If you can go for a slightly different form to store your data in Elastcisearch, you can go use the following:

Define your entity as follows (I am omitting getter/setter for brevity):

@Document(indexName = "innerdata")
public class InnerDataEntity {
    @Id
    private String id;

    @Field(type = FieldType.Object)
    private List<InnerData> innerData;
    
    static class InnerData {
        @Field(type = FieldType.Text)
        private String key;
        private String value;

    }
}

Using this with a Spring Data Elasticsearch Repository will create the index with the following mappings:

{
  "innerdata": {
    "mappings": {
      "properties": {
        "id": {
          "fields": {
            "keyword": {
              "ignore_above": 256,
              "type": "keyword"
            }
          },
          "type": "text"
        },
        "innerData": {
          "properties": {
            "key": {
              "type": "text"
            }
          }
        }
      }
    }
  }
}

The value property is automapped, if you need to search them as well, add the FieldType.Text.

You can then search with the key value by defining a repository like this:

public interface InnerDataRepository extends ElasticsearchRepository<InnerDataEntity, String> {
    SearchHits<InnerDataEntity> searchByInnerData_Key(String key);
}

and use it for example in a controller:

@GetMapping("/{key}")
public SearchHits<InnerDataEntity> allByKey(@PathVariable String key) {

    return repository.searchByInnerData_Key(key);
}

The data that is stored in Elasticsearch looks like this:

{
  "hits": {
    "hits": [
      {
        "_id": "1",
        "_index": "innerdata",
        "_score": 1.0,
        "_source": {
          "id": "1",
          "innerData": [
            {
              "key": "key-1",
              "value": "value-1"
            },
            {
              "key": "key-2",
              "value": "value-2"
            }
          ]
        },
        "_type": "_doc"
      },
      {
        "_id": "2",
        "_index": "innerdata",
        "_score": 1.0,
        "_source": {
          "id": "2",
          "innerData": [
            {
              "key": "key-1",
              "value": "value-1"
            },
            {
              "key": "key-3",
              "value": "value-3"
            }
          ]
        },
        "_type": "_doc"
      }
    ]
    }
  }
}



回答2:


Thank you "@P.J.Meisch", for pointing me the right direction!

I resolved the issue by performing document (json) restructuring, that will be indexed in elasticsearch. It was done by keeping the anonymised patient id at the root level and rest of the patient details in a sub json. Below is my Model class.

@Component
@Document(indexName = "manual_patients") // name must be lower case
@Getter
@Setter
@ToString(callSuper=true, includeFieldNames=true)
// @NoArgsConstructor
public class ManualPatient {

    @Id
    private String _id = UUID.randomUUID().toString();

    @ApiModelProperty(position = 0)
    private String patientId;

    private Map patientDetails;

    public ManualPatient(){}

    public ManualPatient( String patientId, Map patientDetails) {
        this.patientId = patientId;
        this.patientDetails = patientDetails;
    }
}


来源:https://stackoverflow.com/questions/63780364/can-we-avoid-mapping-all-the-fields-to-entity-class-in-springdata-for-elasticsea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!