2

いくつかのフィールドにインデックス付け(トークン化)したいListgetterメソッドがあります。

リストを反復処理し、各文字列にインデックスを付けてフィールドにインデックスを付け、フィールド名にインデックスを追加して、それぞれに異なる名前を付ける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);
   }

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

編集@Fieldアノテーション内で(上記のアナライザーコードを含めずに)Analyzerと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()
4

2 に答える 2

3

ソリューションatmは、カスタムスコープのアナライザーを使用するか、 @AnalyzerDiscriminatorを@AnalyzerDefと一緒に使用します。これは、Hibernate検索フォーラムでも説明されています-https://forum.hibernate.org/viewtopic.php?f=9&t= 1016667

于 2012-07-05T14:27:58.657 に答える
2

私はなんとかこれを機能させることができました。Hibernate Searchは、少なくとも指定されたブリッジが複数のフィールドを作成する場合、analyzer =とが両方指定されている場合、指定されたアナライザーを使用しないように見えます。bridge =

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);
   }

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

于 2012-04-13T02:05:59.997 に答える