Solr自定义Tokenizer Factory随机工作

时间:2014-06-26 09:43:19

标签: java solr lucene tokenize lemmatization

我是Solr的新手,我必须做一个过滤器来将文本文档化,以索引文档,也可以使查询变为lemmatize。

我在为词典文本创建了一个自定义Tokenizer Factory,然后将其传递给标准Tokenizer。

在Solr分析部分进行测试工作相当不错(索引确定,但查询有时会分析文本两次),但在索引文档时,它只分析第一个文档和查询它随机分析(它只分析第一个,和分析另一个你必须等待一段时间)。这不是性能问题,因为我尝试修改文本而不是lemmatizing。

以下是代码:

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”单词,我必须等待几分钟。

会发生什么?

谢谢大家。

1 个答案:

答案 0 :(得分:0)

我非常怀疑在每个查询中调用create方法(首先考虑到初学者的性能问题)。我会采取安全路线并创建一个包裹Tokenizer的{​​{1}},然后覆盖StandardTokenizer方法并在那里开展工作