提问者:小点点

保存合成关键数据到弹性搜索文档


我正在使用hibernate envers来审计我的表的数据并保存在OracleDB中。我正在使用Spring数据弹性搜索通过Java代码读取并保存到弹性搜索索引中的审计数据。我有一个复合键(id和rev),它定义了一个唯一的行来保存数据,但对于弹性搜索,我不能提供复合键。它只接受rev(标识符)列并替换数据。

Hibernate envers背景信息:rev是hibernate提供的默认标识符,对于同时修改的记录列表,它创建相同的rev id:

Eg: id    rev    comments
     1     1      newly created
     2     1      newly created
     1     2      modified
     2     2      modified

前2行是同时创建的,下次我修改这两行并更新时,Hibernateenvers会为1次保存创建相同的rev id。

@Entity
@IdClass(MyEmbeddedId.class)
@Document(indexName = "#{@indexName}", type = "my-document", shards = 1, replicas = 0, refreshInterval = "-1")
@Getter @Setter
public class MyClassAudit {
    @Id
    private Long id;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @org.springframework.data.annotation.Id --> (this is for elastic search _id)
    private Long rev;
}

@Getter @Setter
public class MyEmbeddedId implements Serializable {
    private Long id;
    private Long rev;
}

Java代码:

List<MyClass> list = repository.findById(id);
elasticSearchRepository.saveAll(list)

弹性搜索仓库接口:

public interface MyElasticSearchRepository extends GenericSearchRepository<MyClassAudit, Long> {}

当我将数据保存到弹性搜索时,所有4条记录都应按示例保存,但只有2条记录保存如下:

_id    id    rev    comments
  1     2     1      newly created
  2     2     2      modified

这是因为在弹性搜索中以rev作为标识符,并且正在更新第二条记录。

如何使弹性搜索考虑复合键来维护唯一记录?PS:_id是弹性搜索标识符。由于rev具有Spring数据注释id,因此在弹性搜索中将rev视为标识符


共1个答案

匿名用户

Elasticsearch本身没有复合键的概念。Spring Data Elasticsearch采用@Id注释元素并使用它的toString()方法为Elasticsearch创建id条目(并将字段存储在源中)。

所以——没有试过——你可以使用你的MyEmbeddedId类作为你的MyClass审核类的字段属性,并用@Id对其进行注释。但是你必须在你的类中有这个属性,它不会被合成。

这可能会与hibernate的注释冲突,但我认为在存储之间共享一个实体并使用混合注释不是一个好主意。