Luceneは自分のAnalyzerを書きます

4821 ワード

単純なアナライザ(Analyzer)を実装する例を以下に示す.
public class MyAnalyzer extends Analyzer {  
        public TokenStream tokenStream(String fieldName, Reader reader) {  
            // Token  
            TokenStream stream = new WhitespaceTokenizer(reader);  
            // ,  in、of、it  
            stream = new LengthFilter(stream, 3, Integer.MAX_VALUE);  
            //   
            stream = new PartOfSpeechAttributeImpl.PartOfSpeechTagging  
        Filter(stream);  
            return stream;  
        }  
    }

一般にTokenizerのサブクラスでは実際に語の切り分けが実行される.設定する値は、語に関連する属性termAtt、位置に関連する属性offsetAttです.検索結果でクエリー語をハイライト表示する場合は、位置に関連するプロパティを使用する必要があります.しかし,ユーザクエリ語を分割する際には,一般に位置に関連する属性は必要ない.TokenizerのサブクラスはincrementTokenメソッドを書き換える必要があります.IncrementToken法によりTokenizerが解析した語を遍歴し、取得可能な語がある場合はtrueを返す.最後まで遍歴した場合はfalseを返します.
属性に基づいた方法で不要な語の特徴と所望の語の特徴を区別する.各TokenStreamは、構築時に必要なプロパティを追加します.TokenStreamのライフサイクル全体にわたって属性の参照が保持されます.これにより、TokenStreamインスタンスに関連するすべての属性を取得する際に、属性のタイプが安全であることが保証されます.
 
 protected CnTokenStream(TokenStream input) {  
        super(input);  
        termAtt = (TermAttribute) addAttribute(TermAttribute.class);  
    }

TokenStreamでincrementToken()メソッドでは、1つのtokenストリームは、構築メソッドで宣言されたプロパティのみを操作します.たとえば、分詞のみの場合はTermAttributeのみが必要です.他の属性、例えばPositionIncrementAttributeまたはPayloadAttributeは、このTokenStreamによって無視されます.この場合、他の属性は必要ありません.
   
public boolean incrementToken() throws IOException {  
        if (input.incrementToken()) {  
            final char[] termBuffer = termAtt.termBuffer();  
            final int termLength = termAtt.termLength();  
            if (replaceChar(termBuffer, termLength)) {  
                termAtt.setTermBuffer(output, 0, outputPos);  
            }  
            return true;  
        }  
        return false;  
    }

termAttオブジェクトのtermメソッドで語を返すこともできますが、このメソッドは文字列を返し、文字配列を直接返すtermBufferメソッドの方がパフォーマンスが優れています.次に、順方向最大長マッチングを用いて実現される簡単なTokenizerを示す.
   
public class CnTokenizer extends Tokenizer {  
        private static TernarySearchTrie dic = new 
    TernarySearchTrie("SDIC.txt");  
    //   
        private TermAttribute termAtt;//    
        private static final int IO_BUFFER_SIZE = 4096;  
        private char[] ioBuffer = new char[IO_BUFFER_SIZE];  
     
        private boolean done;  
        private int i = 0;// i   
        private int upto = 0;  
     
        public CnTokenizer(Reader reader) {  
            super(reader);  
            this.termAtt = ((TermAttribute)
    addAttribute(TermAttribute.class));  
            this.done = false;  
        }  
     
        public void resizeIOBuffer(int newSize) {  
            if (ioBuffer.length < newSize) {  
                // Not big enough; create a new array with slight  
                // over allocation and preserve content  
                final char[] newnewCharBuffer = new char[newSize];  
                System.arraycopy(ioBuffer, 0, 
    newCharBuffer, 0, ioBuffer.  
            length);  
                ioBuffer = newCharBuffer;  
            }  
        }  
     
        @Override  
        public boolean incrementToken() throws IOException {  
            if (!done) {  
                clearAttributes();  
                done = true;  
                upto = 0;  
                i = 0;  
                while (true) {  
                    final int length = input.
    read(ioBuffer, upto, ioBuffer.  
                length  
                            - upto);  
                    if (length == -1)  
                        break;  
                    upto += length;  
                    if (upto == ioBuffer.length)  
                        resizeIOBuffer(upto * 2);  
                }  
            }  
     
            if (i < upto) {  
                char[] word = dic.matchLong(ioBuffer, i, upto);  
            //    
                if (word != null)//    
                {  
                    termAtt.setTermBuffer(word, 0, word.length);  
                    i += word.length;  
                } else {  
                    termAtt.setTermBuffer(ioBuffer, i, 1);  
                    ++i;//    
                }  
                return true;  
            }  
            return false;  
        }  
    }