【问题标题】:How to add phrase as a stopword while using lucene analyzer?使用 lucene 分析器时如何添加短语作为停用词?
【发布时间】:2015-01-25 20:55:47
【问题描述】:

我正在使用 Lucene 4.6.1 库。我正在尝试在我的停用词排除列表中添加单词 - hip hop。

如果它写成 - hiphop(作为一个单词),我可以排除它,但是当它写成 hip hop(中间有空格)时,我不能排除它。

以下是我的排除列表逻辑 -

public static final CharArraySet STOP_SET_STEM = new CharArraySet(LUCENE_VERSION, Arrays.asList(

"hiphop","hip hop"

), false);

有关我的自定义分析器逻辑的更多详细信息 -

以下是我的自定义分析器逻辑 -

public final class CustomWordsAnalyzer extends StopwordAnalyzerBase {
  private static final Version LUCENE_VERSION = Version.LUCENE_46;

  // Regex used to exclude non-alpha-numeric tokens
  private static final Pattern ALPHA_NUMERIC = Pattern.compile("^[a-z][a-z0-9_]+$");
  private static final Matcher MATCHER = ALPHA_NUMERIC.matcher("");

  public CustomWordsAnalyzer() {
    super(LUCENE_VERSION, ProTextWordLists.STOP_SET);
  }

  public CustomWordsAnalyzer(CharArraySet stopSet) {
    super(LUCENE_VERSION, stopSet);

  }

  @Override
  protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
    Tokenizer tokenizer = new StandardTokenizer(LUCENE_VERSION, reader);
    TokenStream result = new StandardFilter(LUCENE_VERSION, tokenizer);
    result = new LowerCaseFilter(LUCENE_VERSION, result);
    result = new ASCIIFoldingFilter(result);
    result = new AlphaNumericMaxLengthFilter(result);
    result = new StopFilter(LUCENE_VERSION, result, ProTextWordLists.STOP_SET);

    result = new PorterStemFilter(result);
    result = new StopFilter(LUCENE_VERSION, result, ProTextWordLists.STOP_SET_STEM);
    return new TokenStreamComponents(tokenizer, result);
  }

  /**
   * Matches alpha-numeric tokens between 2 and 40 chars long.
   */
  static class AlphaNumericMaxLengthFilter extends TokenFilter {
    private final CharTermAttribute termAtt;
    private final char[] output = new char[28];

    AlphaNumericMaxLengthFilter(TokenStream in) {
      super(in);
      termAtt = addAttribute(CharTermAttribute.class);
    }

    @Override
    public final boolean incrementToken() throws IOException {
      // return the first alpha-numeric token between 2 and 40 length
      while (input.incrementToken()) {
        int length = termAtt.length();
        if (length >= 3 && length <= 28) {
          char[] buf = termAtt.buffer();
          int at = 0;
          for (int c = 0; c < length; c++) {
            char ch = buf[c];
            if (ch != '\'') {
              output[at++] = ch;
            }
          }
          String term = new String(output, 0, at);
          MATCHER.reset(term);
          if (MATCHER.matches() && !term.startsWith("a0")) {
            termAtt.setEmpty();
            termAtt.append(term);
            return true;
          }
        }
      }
      return false;
    }
  }
}

【问题讨论】:

  • 停用词是一个词,而不是一个短语。
  • 你能为这个自定义分析器 impl 写一个测试吗?

标签: java lucene tokenize


【解决方案1】:

默认的 Lucene 实现无法做到这一点,唯一的方法是创建您自己的 Analyzer 或 TokenStream 或两者,它们将以您需要的方式处理数据/查询(例如过滤短语)

【讨论】:

  • 是的,我已经创建了自己的分析器,但我仍然无法这样做。我想我可能做错了什么。
  • 是的,有可能,请出示您的分析仪代码 - 放在 pastebin 或 gist 中
  • 感谢神秘人!我只是在问题陈述中包含了我的分析器逻辑。任何帮助,将不胜感激。你能看到吗?
猜你喜欢
  • 1970-01-01
  • 2012-02-22
  • 2013-08-03
  • 1970-01-01
  • 2013-01-20
  • 2021-11-13
  • 1970-01-01
  • 2015-11-04
相关资源
最近更新 更多