HibernateSearch查询通过FieldBridge索引的虚拟字段

时间:2016-05-30 14:03:22

标签: hibernate lucene hibernate-search

我在5.0.0.Final版本中使用Hibernate Search。 我在1个表中有1个索引字段。我使用FieldBridge索引该字段:

public class CustomBridge implements FieldBridge {

    @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        MyFieldType file = (ProductOrderJsonEntity) value;
        if (file.getA() != null && file.getB() != null) {
            luceneOptions.addFieldToDocument(name + ".ABconcat", file.getA() + file.getB(), document);
        }
    }
}

我使用FieldBridge索引数据库中不存在的字段,因此当我尝试进行这样的查询时,它会崩溃:

EntityManager em = entityManagerFactory.createEntityManager();
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
em.getTransaction().begin();

QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(MyEntity.class).get();
org.apache.lucene.search.Query luceneQuery = qb.keyword().onFields("productOrder.internalReference", "techId").matching(keyword).createQuery();

javax.persistence.Query jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, MyEntity.class);

...出现以下错误:

org.hibernate.search.exception.SearchException: Unable to find field field.ABconcat in com.something.myapp.MyEntity

显然它试图将我在luceneQuery中给出的字段映射到Object字段(在我的情况下是MyEntity)。

有没有办法查询数据库中不存在的自定义字段的索引?

感谢。

1 个答案:

答案 0 :(得分:1)

我刚刚发现了this post,它解释了您可以查询已通过FieldBridge索引的字段,如下所示:

定位多个字段的查询

int year = datetime.getYear();
int month = datetime.getMonthOfYear();
int day = datetime.getDayOfMonth();

QueryBuilder qb = sm.buildQueryBuilderForClass(BlogEntry.class).get();
Query q = qb.bool()
    .must( qb.keyword().onField("creationdate.year").ignoreFieldBridge().ignoreAnalyzer()
                .matching(year).createQuery() )
    .must( qb.keyword().onField("creationdate.month").ignoreFieldBridge().ignoreAnalyzer()
                .matching(month).createQuery() )
    .must( qb.keyword().onField("creationdate.day").ignoreFieldBridge().ignoreAnalyzer()
                .matching(day).createQuery() )
   .createQuery();

CacheQuery cq = sm.getQuery(q, BlogEntry.class);
System.out.println(cq.getResultSize());
  

关键是:

     

直接定位每个字段,

     

禁用查询的字段桥转换,

     

并且禁用分析仪可能是个好主意。

     

这是一个相当高级的主题,查询DSL将做正确的事情   大多数时候。暂时不用恐慌。

     

但是如果遇到复杂类型需求,那就很有意思了   了解下面发生了什么。