休眠搜索以处理两个不同实体对象的同一索引



两个不同的实体指向数据库中的同一个表,休眠搜索是否可以为它们创建和管理单个索引,因为从技术上讲它们指向同一个表?在我的方案中,创建了两个不同的索引。如何告诉休眠搜索在同一索引上工作

人1.java

@Entity
@Indexed(index = "com.Company.Person")
@Table(name = "Person")
public class Person
{
@Id
@Column(name = "PERSON_ID")
Long id;
@Field
@Column(name = "NAME_FIRST_KEY")
String firstKey;
}

人2.java

@Entity
@Indexed(index = "com.Company.Person")
@Table(name = "Person")
public class WritablePerson
{
@Id
@Column(name = "PERSON_ID")
Long id;
@Field
@Column(name = "NAME_FIRST_KEY")
String firstKey; 
}

我已经将两个类都指向相同的索引"com。公司.人",但它仍然根据索引中的_hibernate_class将它们分开。

我有两个实体指向同一个表的原因是,在我们的生产代码中,我们有两个不同的实体。一个用于写入,另一个用于读取。所以我希望我的索引是同步的。

如果我使用相同的实体进行读写,那么一切都按预期工作。 但是有没有其他方法可以让上述场景工作?

如果我理解正确,当您写入数据库时,您使用WritablePerson实体类型,因此_hibernate_class字段设置为org.company.WritablePerson,但是在搜索时,您希望获得类型org.company.Person的结果,对于最初编写为org.company.WritablePerson的相同文档。

对此没有内置支持。但是,有一些方法可以自己做;您将(可悲地(必须重新实现Hibernate搜索通常开箱即用的部分功能,并且还可能丢失我们为对象加载实现的一些性能优化,但这应该是可能的。

从本质上讲,这个想法是对 ID 执行投影查询,然后显式加载与这些 ID 对应的实体:

List<Person> myQueryMethod(<some params>) {
FullTextEntityManager em = ...;
Query luceneQuery = ...;
FullTextQuery query = em.createFullTextQuery( luceneQuery, WriteablePerson.class );
query.setProjection( org.hibernate.search.engine.ProjectionConstants.ID );
List<Object[]> projections = query.getResultList();
return loadResults( Person.class, projections );
}
<T> List<T> loadResults(Class<T> clazz, List<Object[]> idProjections) {
List<Serializable> ids = new ArrayList<>( idProjections.size() );
for ( Object[] projection : idProjections ) {
ids.add( (Serializable) projection[0] );
}
return em.unwrap( Session.class ).byMultipleIds( clazz )
.with( CacheMode.<pick a cache mode> ) // May be ommitted
.withBatchSize( <pick a batch size> ) // May be ommitted
.multiLoad( ids );
}

使用休眠搜索的选项不依赖于实体在数据库上的映射方式,这是一个完全正交的方面。

您可以让多个实体共享同一索引,无论它们是否存储在同一表中。

您还可以跨多个索引对一个实体进行分片。

最后,您甚至可以使用某些实体属性作为跨分片的鉴别器,以便特定类型的过滤可以从物理索引存储中受益,以匹配最喜欢的过滤器。

_hibernate_class字段是一个技术细节,如果您没有其他实体,它应该不会产生任何影响,但如果您将来决定将另一个实体添加到同一索引中并映射到不同的表,则它可能变得必不可少。

最新更新