elasticsearch - 当数据库上的视图更新时,休眠搜索不更新视图的索引
问题描述
在我的项目中,我们使用的是 Lucene 和 Hibernate Search/ORM 5.9.2。如果在数据库上更新表,它工作得非常好,相同的更改反映在 ES 索引上。但是数据库视图的索引没有更新。值存在于数据库下,但不在索引下。
我需要什么相应的策略/逻辑来通过 Hibernate 搜索来实现这个?
对于任何引用我的实现的代码,都可以在 Java 文件下的已实现代码下找到。
此外,假设我有 2 个类 A 和 B,C 是 A+B 的视图。我将 C 存储在我的弹性索引中。一旦在数据库下更新了 A 和 B,C 是否可能会更新?因为我正在使用 Hibernate 搜索+lucene 注释。
当通过 Hibernate 实体在数据库下更新表时,Hibernate 搜索在索引下更新相同。但是视图不会发生这种行为,因为它们是在 SQL Server 端更新的。这可以通过 Lucene/Hibernate 搜索来实现吗?
解决方案
Hibernate Search 在实体级别运行。所以它看不到您直接在数据库中所做的更改。
为了让 Hibernate Search 管理您的索引,您需要依赖实体。
它真的没有选择以不同的方式做事,因为这就是它的设计目的。
如果对实体进行了更改,您可以实现自己的侦听器层来处理 C 或使 C 成为实体并实现触发器,如果您的数据库可以这样做,则在其上删除更新查询。
如果直接对数据库进行更改,那么您对 Hibernate Search 不走运。或者,每次更改数据库以触发索引时,您都必须在应用程序中触发某些服务。
顺便说一句,您在数据库级别需要此视图吗?因为如果您只在 Elasticsearch 级别需要它,您可以使 C 成为具有 A 和 B 的适当实体,并在另一侧@OneToOne
使用和索引 A 和 B 的内容。这将解决您使用本机 Hibernate Search 的问题。@IndexedEmbedded
@ContainedIn
我想我会尝试类似的东西:
@Entity
@Indexed
public class C {
@Id
@GeneratedValue
private Long id;
@OneToOne(mappedBy = "a")
// you might need a prefix if some fields are common between a and b
@IndexedEmbedded
private A a;
@OneToOne(mappedBy = "b")
// you might need a prefix if some fields are common between a and b
@IndexedEmbedded
private B b;
}
然后在 A 中(B 相同):
@Entity
@Indexed
public class A {
// the existing content of your A class
@OneToOne(cascade = CascadeType.ALL)
@ContainedIn
private C c;
public setC(C c) {
if ( c != null ) {
c.setA( this );
}
this.c = c;
}
}
那么在第一次创建 A 和 B 的时候,还需要创建一个 C 并注入到 A 和 B 中:
C c = new C();
a.setC( c );
b.setC( c );
em.persist( a );
em.persist( c );
完成此操作后,无论何时更新 A 或 B,都应通过@ContainedIn
注释重新索引 C。
推荐阅读
- ssl - Egress TLS Origination 适用于一个域,但不适用于其他域
- java - 如何在没有时区偏移的情况下将日期转换为毫秒?
- c# - 添加 Specflow 功能文件时出现意外的构建错误
- c++ - 为什么我在使用#include 时会出错
在 Clion IDE 中? - linux - 我们什么时候应该在添加系统调用时使用 cond_syscall
- python - timedelta() Python Django的格式显示
- excel - 从 Excel 中打开访问报告会转到“另存为”窗口
- java - Java JPA OrderBy 字段和多列条件搜索不起作用
- ios - 带有 iOS 10.3 的 iPhone 5 和 iPad 4th gen 上非常烦人的 NSPredicate 崩溃
- python - 如何从文本文件中绘制python中的数学函数?