Пользовательский анализатор Lucene для индексирования и запроса
Я работаю над lucene 4.7 и пытаюсь перенести один из анализаторов, которые мы используем в нашей конфигурации solr.
<analyzer>
<charFilter class="solr.HTMLStripCharFilterFactory"/>
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.WordDelimiterFilterFactory"
generateWordParts="1"
generateNumberParts="1"
catenateWords="1"
catenateNumbers="1"
catenateAll="0"
splitOnCaseChange="0"
splitOnNumerics="0"
preserveOriginal="1"
/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
Но я просто не могу понять, как использовать HTMLStripCharFilterFactory и WordDelimiterFilterFactory с конфигурацией, как указано выше. Кроме того, для моего запроса в solr мой анализатор выглядит следующим образом, как я могу добиться того же в lucene.
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords.txt"
/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.PorterStemFilterFactory"/>
</analyzer>
1 ответ:
Документация пакета анализа объясняет, как использовать
CharFilter
. Вы оборачиваете читателя с ним в вашем переопределенном методеinitReader
.Я предполагаю, что проблема с вашим
WordDelimiterFilter
заключается в том, что вы не знаете, как настроить параметры конфигурации, которые вы используете? Вы создаете int для передачи в конструктор, комбинируя соответствующие константы с двоичным и (&
). например:int config = WordDelimiterFilter.GENERATE_NUMBER_PARTS & WordDelimiterFilter.GENERATE_WORD_PARTS; //etc.
Итак, в конце концов вы можете получить что-то например:
Примечание: я переместил//StopwordAnalyzerBase grants you some convenient ways to handle stop word sets. public class MyAnalyzer extends StopwordAnalyzerBase { private final Version version = Version.LUCENE_47; private int wordDelimiterConfig; public MyAnalyzer() throws IOException { super(version, loadStopwordSet(new FileReader("stopwords.txt"), matchVersion)); //Might as well load this config up front, along with the stop words wordDelimiterConfig = WordDelimiterFilter.GENERATE_WORD_PARTS & WordDelimiterFilter.GENERATE_NUMBER_PARTS & WordDelimiterFilter.CATENATE_WORDS & WordDelimiterFilter.CATENATE_NUMBERS & WordDelimiterFilter.PRESERVE_ORIGINAL; } @Override protected TokenStreamComponents createComponents(String fieldName, Reader reader) { Tokenizer source = new WhitespaceTokenizer(version, reader); TokenStream filter = new WordDelimiterFilter(source, wordDelimiterConfig, null); filter = new LowercaseFilterFactory(version, filter); filter = new StopFilter(version, filter, stopwords); filter = new PorterStemFilter(filter); return new TokenStreamComponents(source, filter); } @Override protected Reader initReader(String fieldName, Reader reader) { return new HTMLStripCharFilter(reader); } }
StopFilter
в afterLowercaseFilter
. Это делает его нечувствительным к регистру, если все определения стоп-слов записаны в нижнем регистре. Не знаю, если это проблематично из-за theWordDelimiterFilter
. Если это так, то естьloadStopwordSet
метод, который поддерживает нечувствительность к регистру, но я, честно говоря, не знаю, как его использовать.