我将HibernateSearch 5.7.1.Final
与来自Java的ElasticSearch一起使用。
我的模型中有两种主要类型的对象,
Book
和Journal
,继承自班级Record
并分享一些常见属性:rank
和title
。
一本书的典型排名是1
和期刊的典型值
是2
,但有时可能会有所不同。
我创建了一些默认排名的数据,但对于一本书 我想测试是否会尊重排名值的更新 在查询结果中。
我首先将值设置为0
,然后保存:
...
Book book03 = new Book("Special Book", prus);
book03.setRank(0);
session.save(book03);
然后我使用Hibernate(而不是HibernateSearch)获取对象 机制,并更新值:
session.clear();
session.beginTransaction();
Criteria specialCriteria = session.createCriteria(Book.class);
Book special = (Book) specialCriteria.add(Restrictions.eq("title", "Special Book")).uniqueResult();
special.setRank(6);
session.saveOrUpdate(special);
session.getTransaction().commit();
现在我想获得所有书籍和期刊,并按等级排序。 我使用布尔查询组合书籍查询和期刊查询。 我不知道如何获取特定类型的所有对象,而不包括任何标准,所以我查询 对于标题中包含任何内容的对象。
session.clear();
sessionFactory.getCache().evictEntityRegions();
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.clear();
QueryBuilder bookQueryBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(Book.class).get();
QueryBuilder journalQueryBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(Journal.class).get();
QueryBuilder generalQueryBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(Record.class).get();
org.apache.lucene.search.Query bookLuceneQuery
= bookQueryBuilder.keyword().wildcard().onField("title").matching("*").createQuery();
org.apache.lucene.search.Query journalLuceneQuery
= journalQueryBuilder.keyword().wildcard().onField("title").matching("*").createQuery();
org.apache.lucene.search.Query combinedLuceneQuery = generalQueryBuilder
.bool()
.should( bookLuceneQuery )
.should( journalLuceneQuery )
.createQuery();
FullTextQuery combinedQuery = fullTextSession.createFullTextQuery(combinedLuceneQuery, Record.class);
Sort sort = generalQueryBuilder.sort()
.byField("rank").asc()
.createSort();
combinedQuery.setSort(sort);
List result = combinedQuery.list();
System.out.println("\n\nSearch results for books and journals:");
for(Object object : result)
{
Record record = (Record) object;
System.out.println(record.getTitle());
System.out.println(record.getRank());
System.out.println();
}
问题是我获得了以下结果:
Special Book
6
book01
1
book02
1
book04
1
journal01
2
journal02
2
看起来价值最终更新为6
(打印对象时显示此值),
但在排序期间,使用值0
(这就是为什么Special Book
达到顶峰的原因。)
正如您所看到的,我尝试重置会话以便不会缓存任何内容, 但它没有帮助。
我的另一个假设是rank
不是唯一的元素
这会影响排序,但也会考虑一些相关性,
因为当我不使用布尔值时,问题不会发生
查询。当我只要求书时,Special Book
是最后一本
在结果列表中。但我更喜欢使用组合查询
这样我就可以对结果进行分页。
答案 0 :(得分:2)
默认情况下,Elasticsearch(和Hibernate Search,当它使用Elasticsearch时)接近实时,这意味着在更新影响搜索结果之前会有一点延迟(默认为1秒)查询。将更新考虑在内的时刻称为“刷新”。
您是否尝试在更新后添加一些暂停(例如2秒)?
如果它解决了问题,那么刷新延迟就会导致它。在实际情况下,延迟可能不是问题,因为您很少会执行更新,然后在此之后执行查询,要求索引完全是最新的。
如果您确实有此类要求,则可以将属性hibernate.search.default.elasticsearch.refresh_after_write
设置为true
。但请注意,这会对性能产生负面影响。