【发布时间】:2023-03-12 23:52:01
【问题描述】:
换句话说,通用的 Jackson 标记不足以序列化相同的实体以用作对 Angular 前端的 REST 请求响应并通过 Jest 客户端将对象传递给 Elasticsearch。说,我在实体中有一个图像作为字节数组,我希望将它存储到数据库并传递到前端,但不希望它被 Elasticsearch 索引以降低成本或配额。
现在我必须使用 Jackson 的 JsonView 来标记要用于 Spring Data Elasticsearch 的 ObjectMapper 的字段:
@Entity
@Table(name = "good")
@org.springframework.data.elasticsearch.annotations.Document(indexName = "good", shards = 1, replicas = 0, refreshInterval = "-1")
public class Good implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@org.springframework.data.elasticsearch.annotations.Field(type = FieldType.Keyword)
@JsonView(Views.Elasticsearch.class)
private Long id;
@NotNull
@Column(name = "short_name", nullable = false)
@JsonView(Views.Elasticsearch.class)
@Field(store = true, index = true, type=FieldType.Text)
private String shortName;
@NotNull
@Column(name = "description", nullable = false)
@JsonView(Views.Elasticsearch.class)
@Field(store = true, index = true, type=FieldType.Text)
private String description;
@Lob
@Column(name = "image", nullable = false)
@JsonView(Views.Rest.class)
private byte[] image;
@Column(name = "image_content_type", nullable = false)
@JsonView(Views.Rest.class)
private String imageContentType;
@NotNull
@Column(name = "price", nullable = false)
@JsonView(Views.Elasticsearch.class)
@Field(store = true, index = true, type=FieldType.Integer)
private Integer price;
...
我有一个Views 的类:
public class Views {
public static class Rest{}
public static class Elasticsearch{}
}
并在对应的Bean中设置ObjectMapper:
@Override
public String mapToString(Object object) throws IOException {
log.trace("Object to convert to JSON : {}",object);
log.trace("Converting to json for elasticsearch >>> {}",objectMapper.writer().withView(Views.Elasticsearch.class).writeValueAsString(object));
//log.trace("Converting to json for elasticsearch >>> {}",objectMapper.writeValueAsString(object));
return objectMapper.writerWithView(Views.Elasticsearch.class).writeValueAsString(object);
//return objectMapper.writeValueAsString(object);
}
所以,我必须用@JsonView(Views.Elasticsearch.class) 标记除了忽略到 Elasticsearch 之外的所有字段,这很容易出错。此外,如果我想在那里传递一些参数,如 store 或值类型,则此字段仍然需要使用 @Field。当我有@JsonView(Views.Elasticsearch.class),但没有@Field 时,这些字段是在索引中动态创建的,这允许它们搜索,但不是以所需的方式。
最新的原因是如果我只是将@Field 留在那里并且不将其放在我不想索引到 Elasticsearch 中的字段上,初始索引确实会忽略它们,但是稍后的请求会在实体的序列化方式与 REST 的序列化方式完全相同。并且 index 属性是动态创建的,使得资源被花费在大型二进制对象索引上。所以看起来@Field 用于启动时的初始索引创建,但未配置为与 Spring Data Elasticsearch 的 ObjectMapper 一起使用。
所以,我想让这个 ObjectMapper 只考虑上面带有@Field 的字段,即仅序列化标有@Field 的字段,不使用@JsonView 员工。如何配置?
【问题讨论】:
标签: spring-boot elasticsearch jackson spring-data spring-data-elasticsearch