2017-08-07 14 views
0

JavaのElasticSearchでHibernateSearch 5.7.1.Finalを使用しています。 ranktitle: 私はいくつかの共通の特性をクラスRecord から継承し、共有し、私のモデルのオブジェクトの2つの主要なタイプ、 BookJournalを、持っています。 書籍の一般的なランクは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が結果リストの最後の です。しかし、結果を改ページできるように、組み合わせクエリ を使用することをお勧めします。 (それはElasticsearchを使用して、休止状態の検索、)デフォルトElasticsearchことで

+0

'session.saveOrUpdate(special);' Elasticsearchを直接チェックして、 'SpecialBook'の値を確認しましたか?もしそうなら、それは6か0ですか? – Adonis

+0

コードに* pauses *を追加し、ElasticSearchデータをダンプしました。最初のコードフラグメント実行後は0に設定され、2番目のコードフラグメントは6に設定され、このように維持されます(クエリの実行とソート中は6となります)。 – nuoritoveri

答えて

2

は、あなたの更新が検索クエリの結果に影響を与える前に、若干の遅延(デフォルトは1秒)があるだろうという意味、リアルタイム近くです。更新が考慮される瞬間は、「リフレッシュ」と呼ばれます。

更新後に一時停止(2秒など)を追加してみましたか? 問題が解決する場合は、リフレッシュ遅延が原因です。実際の状況では、更新をほとんど実行せず、その直後にインデックスを完全に最新にする必要があるため、遅延は問題ではない可能性があります。 このような要件がある場合は、hibernate.search.default.elasticsearch.refresh_after_writeというプロパティをtrueに設定することができます。ただし、これはパフォーマンスに悪影響を与えます。

関連する問題