问题描述
我正在使用springdata API实现用于Elasticsearch(es)操作的spring-boot微服务。我在es中建立索引的文档很大,有多个字段(超过100个)。
有没有一种方法可以避免为Java中的Elasticsearch对象定义/硬编码实体类中的所有字段?
我的示例患者JSON可能像这样:
{
"key_1":"value_1","key_2":"value_2","key_3":"value_3",.
.
.
"key_n":"value_n"
}
解决方法
如果您可以使用略有不同的形式将数据存储在Elastcisearch中,则可以使用以下内容:
按以下方式定义您的实体(为简洁起见,我省略了getter / setter):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
color = ('red','#00b050','#00b0f0','yellow')
objects = ('18-25','26-30','31-40','40-50')
y_pos = np.arange(len(objects))
performance = [13,18,16,3]
width = 0.35 # the width of the bars
plt.bar(y_pos,performance,align='center',color=color)
plt.xticks(y_pos,objects)
plt.ylim(0,20) # this adds a little space at the top of the plot,to compensate for the annotation
plt.ylabel('%User',fontsize=16)
plt.title('Age of Respondents',fontsize=20)
width = 0.35
# map names to colors
cmap = dict(zip(performance,color))
# create the rectangles for the legend
patches = [Patch(color=v,label=k) for k,v in cmap.items()]
# add the legend
plt.legend(title='Number of Trips',labels=objects,handles=patches,bbox_to_anchor=(1.04,0.5),loc='center left',borderaxespad=0,fontsize=15,frameon=False)
# add the annotations
for y,x in zip(performance,y_pos):
plt.annotate(f'{y}%\n',xy=(x,y),ha='center',va='center')
将其与Spring Data Elasticsearch存储库一起使用将创建具有以下映射的索引:
@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;
}
}
{
"innerdata": {
"mappings": {
"properties": {
"id": {
"fields": {
"keyword": {
"ignore_above": 256,"type": "keyword"
}
},"type": "text"
},"innerData": {
"properties": {
"key": {
"type": "text"
}
}
}
}
}
}
}
属性是自动映射的,如果您也需要搜索它们,请添加value
。
然后您可以通过定义如下存储库来使用键值进行搜索:
FieldType.Text
并在控制器中使用它:
public interface InnerDataRepository extends ElasticsearchRepository<InnerDataEntity,String> {
SearchHits<InnerDataEntity> searchByInnerData_Key(String key);
}
Elasticsearch中存储的数据如下:
@GetMapping("/{key}")
public SearchHits<InnerDataEntity> allByKey(@PathVariable String key) {
return repository.searchByInnerData_Key(key);
}
,
感谢“ @ P.J。Meisch”,为我指出了正确的方向!
我通过执行文档(json)重组解决了该问题,该重组将在elasticsearch中建立索引。 通过将匿名患者ID保留在根级别并将其余患者详细信息保留在sub json中来完成。下面是我的Model类。
@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;
}
}