使用 Spring 引导从弹性搜索读取,其中 ES 记录没有 _class 属性
Reading from elastic search using Spring boot, where ES record without _class attribute
我正在尝试通过 Spring 数据 + Elastic read/search 弹性搜索中的现有记录 Search.The 弹性搜索中的现有记录没有 _class 属性。
{ "_index": "status-000001",
"_type": "_doc",
"_id": "demo",
"_version": 1,
"_score": null,
"_source": {
"Header.Type": "1",
"Header.Version": "1.0.0",
"Data.sample_rate": "10",
"Data.upload_rate": "60",
"Data.error_code": "0x00000000",
},
}
当我查看映射规则的文档时,文档要求需要 _class。 https://docs.spring.io/spring-data/elasticsearch/docs/current-SNAPSHOT/reference/html/#elasticsearch.mapping.meta-model.rules
但此时,我们无法更新将数据引入 ES 的格式。
索引的映射
{
"status-000001": {
"mappings": {
"properties": {
"Data": {
"properties": {
"error_code": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"sample_rate": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"upload_rate": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"Header": {
"properties": {
"Type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"Version": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
}
对于如何处理这种情况,是否有任何建议?
这里的问题不是缺少 _class
条目。 Spring 数据 Elasticsearch 可以在没有这个的情况下读取实体(它是
在处理继承 类 和集合时确实需要)。
通常像这样的实体将是您所需要的(为简洁起见,我省略了 getter 和 setter):
@Document(indexName = "status")
public class Status {
@Id
private String id;
@Field(name = "Header", type = FieldType.Object)
private Header header;
@Field(name = "Data", type = FieldType.Object)
private Data data;
static class Header {
@Field(name = "Version", type = FieldType.Text)
private String version;
@Field(name = "Type", type = FieldType.Text)
private String type;
}
static class Data {
@Field(name = "error_code", type = FieldType.Text)
private String errorCode;
@Field(name = "sample_rate", type = FieldType.Text)
private String sampleRate;
@Field(name = "upload_rate", type = FieldType.Text)
private String uploadRate;
}
}
问题是您的 elasticsearch 文档具有点符号键中的对象结构:
{
"Header.Type": "1",
"Header.Version": "1.0.0",
"Data.sample_rate": "10",
"Data.upload_rate": "60",
"Data.error_code": "0x00000000"
}
如果 _source
是 Spring Data Elasticsearch 就没有问题:
{
"Header": {
"Type": "1",
"Version": "1.0.0"
},
"Data": {
"sample_rate": "10",
"upload_rate": "60",
"error_code": "0x00000000"
}
}
你可以做的是像这样编写一个自定义转换器(这里没有错误检查):
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import java.util.Map;
@ReadingConverter
public enum MapToStatusConverter implements Converter<Map<String, Object>, Status> {
INSTANCE;
@Override
public Status convert(Map<String, Object> source) {
if (source instanceof Document) {
Document document = (Document) source;
Status status = new Status();
status.setId(document.getId());
Status.Header header = new Status.Header();
header.setType(document.getString("Header.Type"));
header.setVersion(document.getString("Header.Version"));
status.setHeader(header);
Status.Data data = new Status.Data();
data.setSampleRate(document.getString("Data.sample_rate"));
data.setUploadRate(document.getString("Data.upload_rate"));
data.setErrorCode(document.getString("Data.error_code"));
status.setData(data);
return status;
}
return null;
}
}
此转换器需要在 configuring Spring Data Elasticsearch:
时注册
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
.connectedTo("localhost:9200") //
.build();
return RestClients.create(clientConfiguration).rest();
}
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.add(MapToStatusConverter.INSTANCE);
return new ElasticsearchCustomConversions(converters);
}
}
有了这个,您应该能够从 Elasticsearch 读取数据。
我正在尝试通过 Spring 数据 + Elastic read/search 弹性搜索中的现有记录 Search.The 弹性搜索中的现有记录没有 _class 属性。
{ "_index": "status-000001",
"_type": "_doc",
"_id": "demo",
"_version": 1,
"_score": null,
"_source": {
"Header.Type": "1",
"Header.Version": "1.0.0",
"Data.sample_rate": "10",
"Data.upload_rate": "60",
"Data.error_code": "0x00000000",
},
}
当我查看映射规则的文档时,文档要求需要 _class。 https://docs.spring.io/spring-data/elasticsearch/docs/current-SNAPSHOT/reference/html/#elasticsearch.mapping.meta-model.rules
但此时,我们无法更新将数据引入 ES 的格式。
索引的映射
{
"status-000001": {
"mappings": {
"properties": {
"Data": {
"properties": {
"error_code": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"sample_rate": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"upload_rate": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
},
"Header": {
"properties": {
"Type": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"Version": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
}
对于如何处理这种情况,是否有任何建议?
这里的问题不是缺少 _class
条目。 Spring 数据 Elasticsearch 可以在没有这个的情况下读取实体(它是
在处理继承 类 和集合时确实需要)。
通常像这样的实体将是您所需要的(为简洁起见,我省略了 getter 和 setter):
@Document(indexName = "status")
public class Status {
@Id
private String id;
@Field(name = "Header", type = FieldType.Object)
private Header header;
@Field(name = "Data", type = FieldType.Object)
private Data data;
static class Header {
@Field(name = "Version", type = FieldType.Text)
private String version;
@Field(name = "Type", type = FieldType.Text)
private String type;
}
static class Data {
@Field(name = "error_code", type = FieldType.Text)
private String errorCode;
@Field(name = "sample_rate", type = FieldType.Text)
private String sampleRate;
@Field(name = "upload_rate", type = FieldType.Text)
private String uploadRate;
}
}
问题是您的 elasticsearch 文档具有点符号键中的对象结构:
{
"Header.Type": "1",
"Header.Version": "1.0.0",
"Data.sample_rate": "10",
"Data.upload_rate": "60",
"Data.error_code": "0x00000000"
}
如果 _source
是 Spring Data Elasticsearch 就没有问题:
{
"Header": {
"Type": "1",
"Version": "1.0.0"
},
"Data": {
"sample_rate": "10",
"upload_rate": "60",
"error_code": "0x00000000"
}
}
你可以做的是像这样编写一个自定义转换器(这里没有错误检查):
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.elasticsearch.core.document.Document;
import java.util.Map;
@ReadingConverter
public enum MapToStatusConverter implements Converter<Map<String, Object>, Status> {
INSTANCE;
@Override
public Status convert(Map<String, Object> source) {
if (source instanceof Document) {
Document document = (Document) source;
Status status = new Status();
status.setId(document.getId());
Status.Header header = new Status.Header();
header.setType(document.getString("Header.Type"));
header.setVersion(document.getString("Header.Version"));
status.setHeader(header);
Status.Data data = new Status.Data();
data.setSampleRate(document.getString("Data.sample_rate"));
data.setUploadRate(document.getString("Data.upload_rate"));
data.setErrorCode(document.getString("Data.error_code"));
status.setData(data);
return status;
}
return null;
}
}
此转换器需要在 configuring Spring Data Elasticsearch:
时注册@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
.connectedTo("localhost:9200") //
.build();
return RestClients.create(clientConfiguration).rest();
}
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
Collection<Converter<?, ?>> converters = new ArrayList<>();
converters.add(MapToStatusConverter.INSTANCE);
return new ElasticsearchCustomConversions(converters);
}
}
有了这个,您应该能够从 Elasticsearch 读取数据。