2012-04-12 4 views
1

私は、いくつかのフィールドにインデックス付け(トークン化)したいList getterメソッドを持っています。カスタムFieldBridge内でアナライザを使用する

私はリストを反復処理し、フィールド名にインデックスを付加したフィールドに各文字列をインデックス付けして、それぞれに異なる名前を付けるFieldBridge実装を持っています。

私はこのフィールドブリッジで大文字と小文字を区別しない大文字と小文字を区別しないインデックスを作成するために、2つの異なるAnalyzerの実装(CaseSensitiveNGramAnalyzerとCaseInsensitiveNGramAnalyzer)を持っています。

これは私がアナライザを適用するFieldBridgeさ:

public class StringListBridge implements FieldBridge 
{ 

    @Override 
    public void set(String name, Object value, Document luceneDocument, LuceneOptions luceneOptions) 
    { 
     List<String> strings = (List<String>) value; 
     for (int i = 0; i < strings.size(); i++) 
     { 
     addStringField(name + 1, strings.get(i), luceneDocument, luceneOptions); 
     } 
    } 

    private void addStringField(String fieldName, String fieldValue, Document luceneDocument, LuceneOptions luceneOptions) 
    { 
     Field field = new Field(fieldName, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()); 
     field.setBoost(luceneOptions.getBoost()); 
     luceneDocument.add(field); 
    } 
} 
  • はFieldBridgeを使用して、フィールドにアナライザを適用することが可能ですか?
  • もしそうなら、注釈でこれを行うことができますか、それともプログラム的に行う必要がありますか?
  • 後者の場合、アナライザーをパラメーターとして注入できますか?私は、次の線に沿って考えていますが、全くフィールドトークンのストリームに精通していないですしています

等:

private void addStringField(String fieldName, String fieldValue, Document luceneDocument, LuceneOptions luceneOptions) 
    { 
     Field field = new Field(fieldName, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()); 
     field.setBoost(luceneOptions.getBoost()); 
     try 
     { 
     field.setTokenStream(new CaseSensitiveNGramAnalyzer().reusableTokenStream(fieldName, new StringReader(fieldValue))); 
     } 
     catch (IOException e) 
     { 
     e.printStackTrace(); 
     } 
     luceneDocument.add(field); 
    } 

これは正気のアプローチですか?

EDIT以下のようにI(上記分析コードを含むことなく)@Fieldアノテーション内アナライザとFieldBridgeを特定しようとしているが、それはむしろanalyzer =で指定したものよりも、デフォルトのアナライザを使用しているように見えます。

@Fields({ 
     @Field(name="content-nocase", 
      index = Index.TOKENIZED, 
      analyzer = @Analyzer(impl = CaseInsensitiveNgramAnalyzer.class), 
      bridge = @FieldBridge(impl = StringListBridge.class)), 
     @Field(name = "content-case", 
      index = Index.TOKENIZED, 
      analyzer = @Analyzer(impl = CaseSensitiveNgramAnalyzer.class), 
      bridge = @FieldBridge(impl = StringListBridge.class)), 
    }) 
    public List<String> getContents() 

答えて

1

私はこの作業を行うことができました。少なくとも、指定されたブリッジが複数のフィールドを作成する場合は、analyzer =bridge =の両方が指定されている場合、Hibernate Searchは指定されたAnalyzerを使用しないように見えます。手動ブリッジで生成されたフィールドに所望の分析からTokenStreamを通過

は私に期待される結果を得た:

private void addStringField(String fieldName, String fieldValue, Document luceneDocument, LuceneOptions luceneOptions) 
    { 
     Field field = new Field(fieldName, fieldValue, luceneOptions.getStore(), luceneOptions.getIndex(), luceneOptions.getTermVector()); 
     field.setBoost(luceneOptions.getBoost()); 

     // manually apply token stream from analyzer, as hibernate search does not 
     // apply the specified analyzer properly 
     try 
     { 
     field.setTokenStream(analyzer.reusableTokenStream(fieldName, new StringReader(fieldValue))); 
     } 
     catch (IOException e) 
     { 
     e.printStackTrace(); 
     } 
     luceneDocument.add(field); 
    } 

ParameterizedBridgeanalyzerがインスタンスフィールドに格納されている使用するアナライザを指定するために実装されていますこのメソッドが呼び出される前に)。

+0

どのようにアナライザーを作成するのか尋ねられますか?プログラム的に、または@AnalyzerDefで作成された名前にアクセスする方法を考えましたか? – HandyManDan

+0

@HandyManDan私はこれに長い間触れていませんが、手作業でインスタンス化したようです。ここでは、私がこれに取り組んでいた時から関連するコミットがあります。おそらく、周囲のコミットに関連する情報がありますが、おそらく現在のバージョンの修正されたファイル(インデックスは去年にやや変わっています):https:// github .com/zanata/zanata-server/commit/e4b9970393eaf7d2cbddc43048875a897aa7f236 –

+2

ご確認いただきありがとうございます。私は現在、ブリッジ実装の内部で、AnalyzerDefで作成された名前付きアナライザにアクセスする方法がないと考えています。この問題は、https://hibernate.atlassian.net/browse/HSEARCH-1306 – HandyManDan

3

溶液ATMは、カスタムスコープアナライザまたは@AnalyzerDefと共に@AnalyzerDiscriminatorを使用によるものです。これは、Hibernate Searchフォーラムでも議論されています。https://forum.hibernate.org/viewtopic.php?f=9&t=1016667

+0

にも記載されています。in.relation.toのブログ記事もあります。http://in.relation.to/Bloggers/CustomAnalyzersForFieldsDefinedInClassOrFieldBridges – Hardy

+0

@AnalyzerDiscriminatorのアプローチを使用すると、注釈はプロパティだけでなくエンティティ全体に適用されることがわかります。 getAnalyzerDefinitionNameは、そのエンティティのすべてのフィールドに対して呼び出されます。つまり、エンティティに複数のアナライザがある場合は、フィールドparamを参照して正しいアナライザを返す必要があります。 – HandyManDan

関連する問題