Lucene 实战教程第九章自定义 Analyzer

在 Lucene 中,不仅 TokenFilter 我们可以自定义,Analyzer 我们也可以自定义。本文介绍两个扩展 Analyzer 的例子,分别实现扩展停用词,实现字长过滤的功能。

自定义 Analyzer

自定义 Analyzer 只需要做到下面 3 步即可。

  1. 继承自 Analyzer 并覆写 createComponents(String) 方法
  2. 维护自己的停用词词典
  3. 重写 TokenStreamComponents,选择合适的过滤策略
class StopAnalyzerExtend extends Analyzer {
    private CharArraySet stopWordSet;//停止词词典
    public CharArraySet getStopWordSet() {
        return this.stopWordSet;
    }
    public void setStopWordSet(CharArraySet stopWordSet) {
        this.stopWordSet = stopWordSet;
    }
    public StopAnalyzerExtend() {
        super();
        setStopWordSet(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
    }
    /**
     * @param stops 需要扩展的停止词
     */
    public StopAnalyzerExtend(List<String> stops) {
        this();
        /**如果直接为stopWordSet赋值的话,会报如下异常,这是因为在StopAnalyzer中
            有ENGLISH_STOP_WORDS_SET = CharArraySet.unmodifiableSet(stopSet);
         * ENGLISH_STOP_WORDS_SET 被设置为不可更改的set集合
         * Exception in thread "main" java.lang.UnsupportedOperationException
         * at org.apache.lucene.analysis.util.CharArrayMap$UnmodifiableCharArrayMap.put(CharArrayMap.java:592)
         * at org.apache.lucene.analysis.util.CharArraySet.add(CharArraySet.java:105)
         * at java.util.AbstractCollection.addAll(AbstractCollection.java:344)
         * at MyAnalyzer.<init>(AnalyzerDemo.java:146)
         * at MyAnalyzer.main(AnalyzerDemo.java:162)
         */
        //stopWordSet = getStopWordSet();
        stopWordSet = CharArraySet.copy(getStopWordSet());
        stopWordSet.addAll(StopFilter.makeStopSet(stops));
    }
    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        Tokenizer source = new LowerCaseTokenizer();
        return new TokenStreamComponents(source, new StopFilter(source, stopWordSet));
    }
    public static void main(String[] args) throws IOException {
        ArrayList<String> strings = new ArrayList<String>() {{
            add("小鬼子");
            add("美国佬");
        }};
        Analyzer analyzer = new StopAnalyzerExtend(strings);
        String content = "小鬼子 and 美国佬 are playing together!";
        TokenStream tokenStream = analyzer.tokenStream("myfield", content);
        tokenStream.reset();
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
        while (tokenStream.incrementToken()) {
            // 已经过滤掉自定义停用词
            // 输出:playing   together
            System.out.println(charTermAttribute.toString());
        }
        tokenStream.end();
        tokenStream.close();
    }
}

扩展停用词可以过滤掉一些敏感词。

下面我们在来看另外一个例子。自定义 Analyzer 实现字长过滤。

class LongFilterAnalyzer extends Analyzer {
    private int len;
    public int getLen() {
        return this.len;
    }
    public void setLen(int len) {
        this.len = len;
    }
    public LongFilterAnalyzer() {
        super();
    }
    public LongFilterAnalyzer(int len) {
        super();
        setLen(len);
    }
    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        final Tokenizer source = new WhitespaceTokenizer();
        //过滤掉长度<len,并且>20的token
        TokenStream tokenStream = new LengthFilter(source, len, 20);
        return new TokenStreamComponents(source, tokenStream);
    }
    public static void main(String[] args) {
        //把长度小于2的过滤掉,开区间
        Analyzer analyzer = new LongFilterAnalyzer(2);
        String words = "I am a java coder! Testingtestingtesting!";
        TokenStream stream = analyzer.tokenStream("myfield", words);
        try {
            stream.reset();
            CharTermAttribute offsetAtt = stream.addAttribute(CharTermAttribute.class);
            while (stream.incrementToken()) {
                System.out.println(offsetAtt.toString());
            }
            stream.end();
            stream.close();
        } catch (IOException e) {
        }
    }
}

自定义 Analyzer 要注意,Analyzer 里面的两个 tokenStream 方法是不能重写的。因为这两个方法是 final 方法,不能被覆盖的。

Analyzer 是一个抽象类,它要这样的设计其实就是一个装饰器模式,方便我们扩展!

学习一个新的框架,照葫芦画瓢可能是最快捷的方式!

Lucene 实战教程第九章自定义 Analyzer

: » Lucene 实战教程第九章自定义 Analyzer

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/251965.html

(0)
上一篇 2022年5月3日
下一篇 2022年5月3日

相关推荐

发表回复

登录后才能评论