elasticsearch,hibernate-search,Java,elasticsearch,Hibernate Search" /> elasticsearch,hibernate-search,Java,elasticsearch,Hibernate Search" />

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

Java HibernateSearch中的查询不按更新的数据排序,java,elasticsearch,hibernate-search,Java,elasticsearch,Hibernate Search,我正在使用HibernateSearch5.7.1.Final和来自Java的ElasticSearch。 我的模型中有两种主要类型的对象, Book和Journal,它们继承自类Record 并共享一些公共属性:排名和标题。 书籍的典型排名是1,期刊的典型排名是1 是2,但有时可能会有所不同 我创建了一些默认排名的数据,但只针对一本书 我想测试是否会尊重对排名值的更新 在查询结果中 在保存之前,我首先将其值设置为0: ... Book book03 = new Book("Special Bo

我正在使用HibernateSearch
5.7.1.Final
和来自Java的ElasticSearch。 我的模型中有两种主要类型的对象,
Book
Journal
,它们继承自类
Record
并共享一些公共属性:
排名
标题
。 书籍的典型排名是
1
,期刊的典型排名是
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
(这就是为什么
特辑
登上榜首的原因)

如您所见,我尝试重置会话,以便不缓存任何内容, 但这没用

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

默认情况下,Elasticsearch(以及Hibernate Search,当它使用Elasticsearch时)几乎是实时的,这意味着在更新影响搜索查询结果之前会有一点延迟(默认情况下为1秒)。考虑更新的时刻称为“刷新”

您是否尝试在更新后添加一个轻微的暂停(例如2秒)? 如果它解决了问题,则是刷新延迟造成的。在实际情况中,延迟可能不是问题,因为您很少执行更新,然后在更新之后执行查询,这要求索引完全是最新的。 如果您确实有这样的要求,您可以将属性
hibernate.search.default.elasticsearch.refresh\u-after\u-write
设置为
true
。请注意,这将对性能产生负面影响。

默认情况下,Elasticsearch(以及Hibernate Search,当它使用Elasticsearch时)几乎是实时的,这意味着在更新影响搜索查询结果之前会有一点延迟(默认情况下为1秒)。考虑更新的时刻称为“刷新”

您是否尝试在更新后添加一个轻微的暂停(例如2秒)? 如果它解决了问题,则是刷新延迟造成的。在实际情况中,延迟可能不是问题,因为您很少执行更新,然后在更新之后执行查询,这要求索引完全是最新的。
如果您确实有这样的要求,您可以将属性
hibernate.search.default.elasticsearch.refresh\u-after\u-write
设置为
true
。请注意,这将对性能产生负面影响。

鉴于这一行
session.saveOrUpdate(特殊)
您是否已直接在Elasticsearch中进行了检查,以检查您的
专用书籍的值?如果是6还是0?我在代码中添加了暂停,并转储了ElasticSearch数据。第一次执行代码片段后,它被设置为0,第二次执行后,它被设置为6,并保持不变(因此在查询执行和排序期间它也是6)
您是否已直接在Elasticsearch中进行了检查,以检查您的
专用书籍的值?如果是6还是0?我在代码中添加了暂停,并转储了ElasticSearch数据。在第一次代码片段执行之后,它被设置为0,在第二次代码片段执行之后,它被设置为6,并且保持不变(因此在查询执行和排序期间它也是6)。