0

我是 Solr 的新手,我必须做一个过滤器来对文本进行词形还原以索引文档以及对查询进行词形还原。

在将其传递给标准分词器之前,我为词形还原文本创建了一个自定义分词器工厂。

在 Solr 分析部分进行测试工作得相当好(在索引上可以,但在查询上有时会分析两次文本),但是在索引文档时它只分析第一个文档,而在查询时它随机分析(它只分析第一个,然后分析另一个你必须等待一点时间)。这不是性能问题,因为我尝试修改文本而不是词形还原。

这是代码:

package test.solr.analysis;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Map;
import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.util.AttributeSource.AttributeFactory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.standard.StandardTokenizer;

//import test.solr.analysis.TestLemmatizer;

    public class TestLemmatizerTokenizerFactory extends TokenizerFactory {
    //private TestLemmatizer lemmatizer = new TestLemmatizer();
    private final int maxTokenLength;

    public TestLemmatizerTokenizerFactory(Map<String,String> args) {
        super(args);
        assureMatchVersion();
        maxTokenLength = getInt(args, "maxTokenLength", StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
        if (!args.isEmpty()) {
            throw new IllegalArgumentException("Unknown parameters: " + args);
        }
    }

    public String readFully(Reader reader){
        char[] arr = new char[8 * 1024]; // 8K at a time
        StringBuffer buf = new StringBuffer();
        int numChars;
        try {
            while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
                buf.append(arr, 0, numChars);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("### READFULLY ### => " + buf.toString());
        /*
            The original return with lemmatized text would be this:
            return lemmatizer.getLemma(buf.toString());

            To test it I only change the text adding "lemmatized" word
        */
        return buf.toString() + " lemmatized";
    }

    @Override
    public StandardTokenizer create(AttributeFactory factory, Reader input) {
        // I print this to see when enters to the tokenizer
        System.out.println("### Standar tokenizer ###");
        StandardTokenizer tokenizer = new StandardTokenizer(luceneMatchVersion, factory, new StringReader(readFully(input)));
        tokenizer.setMaxTokenLength(maxTokenLength);
        return tokenizer;
    }
}

有了这个,它只索引第一个添加单词“lemmatized”到文本的文本。然后在第一次查询时,如果我搜索“example”这个词,它会查找“example”和“lemmatized”,所以它会返回第一个文档。在下一次搜索时,它不会修改查询。要进行一个新的查询,在查询中添加“lemmatized”词,我必须等待几分钟。

怎么了?

谢谢你们。

4

1 回答 1

0

我非常怀疑create每个查询都会调用该方法(首先想到性能问题)。我会采取安全路线并创建一个Tokenizer包装 a StandardTokenizer,然后重写该setReader方法并在那里完成我的工作

于 2014-06-26T10:55:25.663 回答