Spring 数据弹性搜索:在 POJO 接口上使用 @Document 注释 class 不工作

Spring data elasticsearch: Using @Document annotation on POJO interface class not working

我正在将一个应用程序迁移到最新的 spring-boot 版本(使用版本 2.5.4 的 maven spring-boot-dependencies)。

我有一个名为 Customer 的接口,我有该接口的两个实现(BusinessCustomerPrivateCustomer

三个类是这样注释的:

@Document(indexName = "customers", type = "customer")
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "customerType"
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = BusinessCustomer.class, name = "BUSINESS_CUSTOMER"),
        @JsonSubTypes.Type(value = PrivateCustomer.class, name = "PRIVATE_CUSTOMER")
})
public interface Customer {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "customerType",
        defaultImpl = BusinessCustomer.class
)
@Entity
@Document(indexName = "customers", type = "customer")
public class BusinessCustomer implements Serializable, Customer, Cloneable {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "customerType",
        defaultImpl = PrivateCustomer.class
)
@Entity
@Document(indexName = "customers", type = "customer")
public class PrivateCustomer implements Serializable, Customer, Cloneable {

为了查询索引“客户”,我曾经使用如下代码:

elasticsearchOperations.count(query, Customer.class);

但这不再有效了。我在运行时遇到错误:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate Customer using constructor NO_CONSTRUCTOR with arguments ] with root cause org.springframework.beans.BeanInstantiationException: Failed to instantiate [Customer]: Specified class is an interface

像这样在同一个索引中不能再有两个不同的 类 了吗?现在是否可以通过 ElasticsearchCustomConversions 以某种方式完成此操作?

SpringData Elasticsearch中的MappingElasticsearchConverter在接口上不起作用,而是依赖于在实体上设置的@Document@Field注释class.

所有 Spring 数据模块 - 不仅是 Spring Data Elasticsearch - 使用 PersistentEntity 的概念,即关于要存储的 class 的元信息。而 PersistentPropertys,这是关于 class 属性的元信息。对于 Spring Data Elasticsearch,这是有关 Elasticsearch 中字段名称的信息,它是类型, 日期格式等信息

一个 @Document 注释 class 与一个索引相关联。由于版本 7 Elasticsearch 不再支持在一个索引中包含多种类型。

因此您应该将不同的实体存储在两个索引中:

@Document(indexName="business-customers")
class BusinessCustomer {
    // ...
}

@Document(indexName="private-customers")
class PrivateCustomer {
    // ...
}

在一个调用中搜索这两个索引并返回不同的数据是可能的,我写了一篇博客 post 关于如何做到这一点 (https://www.sothawo.com/2021/05/reading-different-entities-from-multiple-indices-with-one-call-using-spring-data-elasticsearch/)。