在我的项目中,我们使用Lucene和Hibernate Search / ORM 5.9.2。如果在数据库中更新了表,则工作得很好,相同的更改也反映在ES索引上。但是数据库视图的索引不会更新。值存在于数据库下,但不存在于索引下。
我需要通过Hibernate搜索实现哪些相应的策略/逻辑?
有关引用我的实现的任何代码都可以在implemented code under the Java files下找到。
此外,假设我有2个类A和B,而C是A + B的视图。我将C存储在弹性索引中。一旦在数据库下更新了A和B,C是否有可能被更新?当我使用Hibernate search + lucene注释时。
当通过Hibernate实体在数据库下更新表时,Hibernate搜索将在索引下对其进行更新。但是,由于视图是在SQL Server端更新的,因此不会发生这种现象。是否可以通过Lucene /休眠搜索来实现?
答案 0 :(得分:1)
休眠搜索在实体级别运行。因此,它看不到您直接在数据库中所做的更改。
要让Hibernate Search管理索引,您需要依赖实体。
实际上,它是别无选择的,因为这是它的设计宗旨。
如果对实体进行了更改,则可以实现自己的侦听器层来处理C或使C成为实体,并实现触发器(如果数据库可以做到的话,则放弃对它的更新查询)。
如果更改是直接对数据库进行的,那么使用Hibernate Search会很不幸。或者,每次更改数据库以触发索引时,您都必须在应用程序中触发某些服务。
顺便说一句,您是否需要数据库级别的此视图?因为如果仅在Elasticsearch级别上需要它,则可以使C成为对A和B具有@OneToOne
的适当实体,并使用@IndexedEmbedded
和@ContainedIn
对A和B的内容进行索引另一边。这样可以解决您的原生Hibernate Search问题。
我想我会尝试:
@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。