HibernateSearch 中的查询不按更新数据排序

The query in HibernateSearch does not sort by updated data

我正在使用 HibernateSearch 5.7.1.Final 和来自 Java 的 ElasticSearch。 我的模型中有两种主要类型的 object, BookJournal,继承自 class Record 并共享一些共同的属性:ranktitle。 一本书的典型排名是 1 和期刊的典型值 是 2,但有时可能不同。

我创建了一些具有默认排名的数据,但对于一本书 我想测试是否会尊重排名值的更新 在查询结果中。

保存前我先把它的值设为0

...
Book book03 = new Book("Special Book", prus);
book03.setRank(0);
session.save(book03);

然后我使用 Hibernate(不是 HibernateSearch)获得 object 机制,并更新值:

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();

现在我想获取所有的书籍和期刊,并按排名排序。 我使用布尔查询组合了书籍查询和期刊查询。 我不知道如何在不包含任何条件的情况下获取特定类型的所有 object,所以我查询 object 标题中有任何内容。

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 (这个值在打印时显示object), 但在排序过程中使用了值 0 (这就是 Special Book 登上顶峰的原因)。

如您所见,我尝试重置 session 以便不缓存任何内容, 但它没有帮助。

我的另一个假设是 rank 不是唯一的元素 这会影响排序,但也会考虑一些 相关性 , 因为当我不使用布尔值时问题不会发生 询问。当我只求书时,Special Book是最后一个 在结果列表中。但我更愿意使用组合查询 这样我就可以对结果进行分页了。

默认情况下,Elasticsearch(和 Hibernate Search,当它使用 Elasticsearch 时)接近实时,这意味着在您更新之前会有轻微的延迟(默认情况下为 1 秒)影响搜索查询的结果。考虑更新的时刻称为 "refresh".

您是否尝试在更新后添加轻微的停顿(例如 2 秒)? 如果它解决了问题,那么就是刷新延迟导致的。在现实世界的情况下,延迟可能不是问题,因为您很少会执行更新,然后在需要索引完全最新的情况下立即执行查询。 如果你确实有这样的需求,你可以将 属性 hibernate.search.default.elasticsearch.refresh_after_write 设置为 true。不过请注意,这会对性能产生负面影响。