【问题标题】:HibernateSearch querying on virtual fields indexed via FieldBridgeHibernateSearch 查询通过 FieldBridge 索引的虚拟字段
【发布时间】:2016-05-31 16:40:18
【问题描述】:

我在 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)。

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

谢谢。

【问题讨论】:

    标签: hibernate lucene hibernate-search


    【解决方案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 会做正确的事 大多数时候。暂时不必惊慌。

    但如果您遇到复杂类型的需求,有趣的是 了解下面发生了什么。

    【讨论】:

    • 您的答案是正确的,除此之外 - 假设您可以升级到 Hibernate Search 5.5.3 - 您可以使用 org.hibernate.search.bridge.MetadataProvidingFieldBridge 声明您在 FieldBridge 中创建的字段。这应该会改善 DSL 集成。另见hibernate.atlassian.net/browse/HSEARCH-2021
    猜你喜欢
    • 1970-01-01
    • 2012-12-27
    • 2019-12-12
    • 2020-05-27
    • 2015-02-04
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多