2017-10-18 24 views
0

私は、 'firstName'、 'lastName'、 'secondLastName'という文字列フィールドを持つ 'Patient'というエンティティを持っています(スペイン語では、 )Hibernate Search:別の列でフルネームを検索する方法

患者を名前で検索するためのテキストボックスが表示されています。ユーザーはfirstName、lastName、secondLastName、またはこれらの組み合わせを任意の順序で入力できます。

のfirstName:マウリシオ、 lastNameの:Ubilla、 secondLastName:カルバハル、

私は "マウリシオUbillaカルバハル" あるいは "マウリシオUbilla" を検索する場合、私がトップに表示されますことを期待し、私の名前を持つ例えば 、結果リスト 質問は次のとおりです。

1-これらの3つのフィールドのインデックスはどのように定義する必要がありますか?私は次のようにしました:

@Indexed 
class Patient { 
    ... 
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO) 
    protected String firstName = new String(); 
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO) 
    protected String lastName = new String(); 
    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO) 
    protected String secondLastName = new String(); 
    ... 
} 

2-どのようにクエリをビルドしますか?私はこれをした:

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();   
Query luceneQuery = qb.keyword().onFields("firstName", "lastName", "secondLastName").matching(name).createQuery(); 

しかし、これは私のために働いていない。それは何も例外をスローしていない、それは何も戻っていないことだけです。 "Mauricio"だけを検索しても、何も返されません。

しかし、私は私のfirstNameと一致するようにクエリを変更した場合:

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();   
Query luceneQuery = qb.keyword().onFields("firstName").matching(name).createQuery(); 

私は「マウリシオ」を検索する場合、それは動作します。

私は間違っていますか? 3列の複合インデックスを定義する方法はありますか?クエリを別の方法で構築する必要がありますか?それはあなたがバグに実行されていることを非常に可能性がありますので 、私はHibernateの検索4.5.1以上にHibernate 4.3およびJava 1.7

答えて

2

あなたは休止状態を検索するのは非常に古いバージョンを使用しているを使用しています、私はところで を:(助けてくださいあなたは本当に少なくともHibernate Search 5.6/Hibernate ORM 5.1、あるいは5.8/ORM 5.2 Search(Java 8が必要です)へのアップグレードについて考えるべきです。

もしあなたがそうでなければ、それはもっと最近のバージョンで解決されました。 ..別の一般的な解決策は、内容が連結された名前である一時的なプロパティをインデックスすることです:

@Indexed 
class Patient { 
    ... 
    @Field 
    protected String firstName = ""; 
    @Field 
    protected String lastName = ""; 
    @Field 
    protected String secondLastName = ""; 
    ... 
    @javax.persistence.Transient 
    @Field 
    public String getFullName() { 
     // TODO null safety 
     return firstName + " " + lastName + " " + secondLastName; 
    } 
    ... 
} 
フィールドのインデックスを作成すると、一部の最適化を無効にしますので、あなたの最初のソリューションとは逆に、これは、パフォーマンスに悪影響を及ぼします、という

QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Patient.class).get();   
Query luceneQuery = qb.keyword().onFields("fullName").matching(name).createQuery(); 

注:0

は、このfullNameに問い合わせます。しかし、少なくともそれはうまくいくはずです。

+0

ありがとうリンクから取得されます!それは私がやっていることです、それは正常に動作します。また、新しいバージョンのhibernateへのアップグレードに関する助言にも感謝します。私はすぐにそれをやらなければならないようだ。 –

0

2番目の質問に答えるにはあなたは、キーワードではなく文章として句を使用して聴取することができます。

にHibernate Searchは、様々な戦略を使用して組み合わせたクエリをサポートしています。

をお薦め:サブクエリのマッチング要素が含まれている必要があり、クエリ

-MUST:クエリは、サブクエリのマッチング要素が含まれている必要があり

-MUST NOT:クエリにサブクエリの一致する要素を含めることはできません。

集計はブール値のAND、ORおよびNOTと似ています。

Query combinedQuery = queryBuilder 
    .bool() 

    .must(queryBuilder.phrase() 
    .onField("productName).sentence("samsung galaxy s8") 
    .createQuery()) 

    .must(queryBuilder.keyword() 
    .onField("productCategory").matching("smartphone") 
    .createQuery()) 

    .createQuery(); 


    // wrap Lucene query in an Hibernate Query object 
    org.hibernate.search.jpa.FullTextQuery jpaQuery = 
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class); 

    // execute search and return results (sorted by relevance as default) 
    @SuppressWarnings("unchecked") 
    List<Product> results = jpaQuery.getResultList(); 

このリファレンスでは、http://www.baeldung.com/hibernate-search

関連する問題