HibernateSearch 查询通过 FieldBridge 索引的虚拟字段
HibernateSearch querying on virtual fields indexed via FieldBridge
我使用的是 5.0 版的 Hibernate Search。0.Final。
我在 1 table 中索引了 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 中提供的字段映射到对象字段(在我的例子中是 MyEntity)。
有什么方法可以查询数据库中不存在的自定义字段的索引吗?
谢谢。
我刚刚发现 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());
The key is to:
target directly each field,
disable the field bridge conversion for the query,
and it’s probably a good idea to disable the analyzer.
It’s a rather advanced topic and the query DSL will do the right thing
most of the time. No need to panic just yet.
But in case you hit a complex type needs, it’s interesting to
understand what is going on underneath.
我使用的是 5.0 版的 Hibernate Search。0.Final。 我在 1 table 中索引了 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 中提供的字段映射到对象字段(在我的例子中是 MyEntity)。
有什么方法可以查询数据库中不存在的自定义字段的索引吗?
谢谢。
我刚刚发现 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());
The key is to:
target directly each field,
disable the field bridge conversion for the query,
and it’s probably a good idea to disable the analyzer.
It’s a rather advanced topic and the query DSL will do the right thing most of the time. No need to panic just yet.
But in case you hit a complex type needs, it’s interesting to understand what is going on underneath.