6

カスタム アナライザーでフィールドを分析すると、termvector に無効なオフセットが与えられますが、標準のアナライザーでは問題ありません。これが私のアナライザー コードです。

public class AttachmentNameAnalyzer extends Analyzer {
    private boolean stemmTokens;
    private String name;

    public AttachmentNameAnalyzer(boolean stemmTokens, String name) {
        super();
        this.stemmTokens    = stemmTokens;
        this.name           = name;
    }

    @Override
    public TokenStream tokenStream(String fieldName, Reader reader) {
        TokenStream stream = new AttachmentNameTokenizer(reader);
        if (stemmTokens)
            stream = new SnowballFilter(stream, name);
        return stream;
    }

    @Override
    public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {
        TokenStream stream = (TokenStream) getPreviousTokenStream();

        if (stream == null) {
            stream = new AttachmentNameTokenizer(reader);
            if (stemmTokens)
                stream = new SnowballFilter(stream, name);
            setPreviousTokenStream(stream);
        } else if (stream instanceof Tokenizer) {
            ( (Tokenizer) stream ).reset(reader);
        }

        return stream;
    }
}

この「ヘルプが必要」の何が問題なのですか

4

2 に答える 2

0

以前にアナライザーのコードを投稿したように、アナライザーに問題があります。実際には、トークン化されるテキストの新しいエントリごとにトークンストリームを休ませる必要があります。

 public TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {
        TokenStream stream = (TokenStream) getPreviousTokenStream();

        if (stream == null) {
            stream = new AttachmentNameTokenizer(reader);
            if (stemmTokens)
                stream = new SnowballFilter(stream, name);
            setPreviousTokenStream(stream); // --------------->  problem was here 
        } else if (stream instanceof Tokenizer) {
            ( (Tokenizer) stream ).reset(reader); 
        }

        return stream;
    }

前のトークンストリームを設定するたびに、次のテキストフィールドを個別にトークン化する必要があります。常に最後のトークンストリームの終了オフセットで始まり、新しいストリームのベクトルオフセットという用語が間違っていますが、このように正常に動作します

ublic TokenStream reusableTokenStream(String fieldName, Reader reader) throws IOException {
            TokenStream stream = (TokenStream) getPreviousTokenStream();

            if (stream == null) {
                stream = new AttachmentNameTokenizer(reader);
                if (stemmTokens)
                    stream = new SnowballFilter(stream, name);
            } else if (stream instanceof Tokenizer) {
                ( (Tokenizer) stream ).reset(reader); 
            }

            return stream;
        }
于 2011-07-04T08:00:20.347 に答える
0

Lucene のどのバージョンを使用していますか? 3x ブランチのスーパー クラス コードと、バージョンごとの動作の変更を見ています。

が計算されるpublic final boolean incrementToken()場所のコードを確認することをお勧めします。offset

私もこれを見ます:

/**
 * <p>
 * As of Lucene 3.1 the char based API ({@link #isTokenChar(char)} and
 * {@link #normalize(char)}) has been depreciated in favor of a Unicode 4.0
 * compatible int based API to support codepoints instead of UTF-16 code
 * units. Subclasses of {@link CharTokenizer} must not override the char based
 * methods if a {@link Version} >= 3.1 is passed to the constructor.
 * <p>
 * <p>
 * NOTE: This method will be marked <i>abstract</i> in Lucene 4.0.
 * </p>
 */

ところで、次のように switch ステートメントを書き換えることができます

@Override
protected boolean isTokenChar(int c) {
    switch(c)
    {
        case ',': case '.':
        case '-': case '_':
        case ' ':
            return false;
        default:
            return true;
    }
}
于 2011-06-11T15:21:10.717 に答える