2

我有一个 List getter 方法,我想将它索引(标记化)到多个字段中。

我有一个 FieldBridge 实现,它遍历列表并将每个字符串索引到一个字段中,并将索引附加到字段名称中,以便为每个字符串提供不同的名称。

我有两个不同的分析器实现(CaseSensitiveNGramAnalyzer 和 CaseInsensitiveNGramAnalyzer),我想与此 FieldBridge 一起使用(使字段的索引区分大小写和不区分大小写)。

这是我想将分析器应用到的 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 Search 论坛上进行了讨论 - https://forum.hibernate.org/viewtopic.php?f=9&t=1016667

于 2012-07-05T14:27:58.657 回答
2

我设法让这个工作。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 回答