2017-08-07 20 views
0

我正在使用HibernateSearch 5.7.1.Final和Java的ElasticSearch。 我在我的模型兩種主要類型的對象, BookJournal,從Record類 繼承和一些共同的特性:ranktitle。 典型的排名爲1,期刊 的典型值爲2,但有時可能會有所不同。HibernateSearch中的查詢不會按更新數據排序

我使用默認排名創建了一些數據,但是對於一本書 我想測試查詢結果中排名值的更新是否受到 的尊重。

我第一次把它保存前的價值,以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

鑑於此行'session.saveOrUpdate(special);'您是否直接檢查Elasticsearch以檢查'SpecialBook'的值?如果是6或0? – Adonis

+0

我在代碼中添加了*暫停*並轉儲了ElasticSearch數據。在第一個代碼片段執行後,它被設置爲0,在第二個代碼片段被設置爲6並且它保持這樣(因此在查詢執行和排序期間它也是6)。 – nuoritoveri

回答

2

默認情況下,Elasticsearch(和Hibernate Search在使用Elasticsearch時)爲接近實時,這意味着在更新影響搜索查詢結果之前會稍微延遲(默認爲1秒)。更新被考慮的時刻稱爲「刷新」。

您是否嘗試在更新後添加輕微暫停(例如2秒)? 如果它解決了這個問題,那麼更新延遲導致它。在現實世界中,延遲可能不成問題,因爲您很少執行更新,然後在需要索引完全更新之前執行查詢。 如果您確實有這樣的要求,您可以將屬性hibernate.search.default.elasticsearch.refresh_after_write設置爲true。但請注意,這會對性能造成負面影響。