Hibernate 搜索为两个不同的 Entity 对象处理相同的索引

Hibernate search to work on the same index for two different Entity objects

两个不同的实体指向数据库中的同一个 Table,hibernate search 可以为它们创建和管理一个索引吗,因为从技术上讲它们指向同一个 table?在我的场景中,创建了两个不同的索引。我怎样才能告诉休眠搜索在同一个索引上工作

Person1.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;
}

Person2.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.Company.Person",但它仍然根据索引中的 _hibernate_class 将它们分开。

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

如果我使用相同的实体进行读取和写入,那么一切都会按预期进行。 但是有没有其他方法可以使上述情况起作用?

您对 Hibernate Search 的选择不取决于实体在数据库上的映射方式,这是一个完全正交的方面。

你可以有multiple entities share the same index,不管它们如何存储在同一个table中。

您也可以拥有一个实体sharded across multiple indexes

最后,您甚至可以 use some entity property as discriminator across shards 以便特定类型的过滤可以从物理索引存储中获益,以匹配最喜欢的过滤器。

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

如果我没理解错的话,当你写入数据库时​​,你使用的是WritablePerson实体类型,因此_hibernate_class字段设置为org.company.WritablePerson,但是在搜索时你想要对于最初写为 org.company.WritablePerson.

的相同文档,获取类型 org.company.Person 的结果

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

这个想法本质上是对 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 );
}