Solr - синонимы, содержащие несколько слов

Быстрый вопрос, я не знаю, как иметь дело с синонимами, которые содержат пространство! У меня есть следующая конфигурация:

Файл конфигурации SOLR

<fieldType ... >
  <analyzer type="index">
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
            <filter class="solr.WordDelimiterFilterFactory" 
                            catenateWords="1" 
                            preserveOriginal="1"
                            splitOnCaseChange="1"
                            generateWordParts="1" 
                            generateNumberParts="1"         
                            catenateNumbers="1" 
                            catenateAll="1" 
                            />
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="30" side="front"/>
  </analyzer>
  <analyzer type="query">    
    <charFilter class="solr.MappingCharFilterFactory" mapping="mapping-ISOLatin1Accent.txt"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.LengthFilterFactory" min="2" max="70" />
    <filter class="solr.SynonymFilterFactory" synonyms="syn.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
 </analyzer>
</fieldType>

Мой файл: syn.txt

st., st => saint
istambul => istanbul
airport, apt => aéroport
NYC => New York
pt., pt => port
brussels => bruxelles

Все работало отлично, за исключением синонима:

"NYC => New York"

Я провел некоторое исследование, и я нашел следующее:

Имейте в виду, что, хотя SynonymFilter будет с удовольствием работать с синонимами, содержащими несколько слов (например: "морское печенье, морское бисцит, морское печенье" )

Рекомендуемым подходом к синонимам, подобным этому, является расширение синонима при индексировании. Это связано с тем, что есть две потенциальные проблемы, которые могут быть достигнуты во время запроса:

Lucene QueryParser выполняет токенизацию на белом фоне перед тем, как передать какой-либо текст анализу, поэтому, если человек ищет слова "морской бисквит", анализатору будут даны слова "море" и "бисцит" отдельно, и они не будут знать, что они соответствуют синониму.

Поиск фразы (т.е. "морской бисквит" ) заставит QueryParser передать всю строку в анализатор, но если SynonymFilter настроен на расширение синонимов, тогда, когда QueryParser получает результирующий список токенов назад Analyzer, он построит MultiPhraseQuery, который не будет иметь желаемого эффекта.

Это связано с ограниченным механизмом, доступным для анализатора, чтобы указать, что два члена занимают одно и то же положение: нет способа указать, что "фраза" занимает ту же позицию, что и термин.

В нашем примере полученный MultiPhraseQuery будет "(море | море | морское печенье) (biscuit | biscit)", которое не соответствовало бы простому случаю "морского печенья", имеющему место в документе

Итак, я попытался изменить свой файл конфигурации и добавить свои фильтры при индексировании, но он не работает.

Есть ли у чего-то идеи?

Ответ 1

Вы выполняете явное сопоставление с помощью =>.

документация Solr говорит

Явные сопоставления соответствуют любой последовательности токенов в LHS "= > " и replace со всеми альтернативами в RHS. Эти типы отображений игнорируют параметр расширения в схеме.

Итак, я предполагаю, что если вы ищете NYC, вы ничего не получите назад, так как он был заменен на New York во время индекса.

Вместо этого вы можете попробовать объявить их как эквивалентные синонимы? то есть NYC, New York вместо NYC => New York.

Тогда я верю, что вы можете найти любой из них, и результат будет таким же.

Ответ 2

Проблема заключается в том, что синонимы solr имеют тенденцию вызывать проблемы, когда число слов в первой фразе меньше количества слов во второй фразе. Когда это происходит, токены переполняются в позиции других токенов.

У меня есть обходной путь для этой проблемы, но для этого требуется два использования solr.SynonymFilterFactory по индексу и времени запроса.

Вот так:

<filter class="solr.SynonymFilterFactory" synonyms="multi_word_conversion.txt" 
ignoreCase="true" expand="true" />

<filter class="solr.SynonymFilterFactory" synonyms="layor_two_syns.txt" 
ignoreCase="true" expand="true"/>

В первом фильтре у вас будет: New York = > New_York

Во втором фильтре: NYC = > New_York

Теперь поиск в Нью-Йорке вернет результаты, содержащие Нью-Йорк и наоборот.

В последнем примечании: Этот метод не будет работать, если он не находится в индексе и времени запроса.

Ответ 3

О

st., st => saint

Я думаю, вы должны сделать так:

st. => saint
st => saint

О

NY => New York

Я столкнулся с подобной проблемой и пришел к выводу, что это потому, что синтаксический анализ выполняется ПЕРЕД заменой синонимов, что, вероятно, вызывает проблему при многократном слове. Я обнаружил, что можно включить парсер в SynonymFactory:

<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" tokenizerFactory="solr.KeywordTokenizerFactory" /> 

Я только что испытал это, я получил гораздо лучшие результаты, но еще не ожидал. Как ни странно, при добавлении KeywordTokenizerFactory кажется положительным, добавление WhitespaceTokenizerFactory или StandardTokenizerFactory, похоже, ничего не меняет.

Кстати, если не использовать черепицу, это уже должно быть хорошо.

Ответ 4

основываясь на ответе Pr Shadoko:

Посмотрите, как работает ваш анализатор, например. с

http://localhost/solr/analysis/field?analysis.fieldvalue=EXAMPLE-KEYWORDS&q=EXAMPLE-KEYWORD%203&analysis.fieldname=EXAMPLEFIELD&analysis.showmatch=true

analysis/field - обработчик запросов "вне коробки" (помещенный в файл solrconfig.xml). Здесь вы найдете список параметров. ( "analysis.query" не работает для меня, поэтому мне пришлось использовать "q" )

Поскольку SynonymFilter анализирует (сокращает) входящий текст перед соответствием любому синониму, синонимы с несколькими словами не будут попадать в хит. Хитрость заключается в том, чтобы сказать SynonymFilter взять синтаксический анализатор, который на самом деле не анализируется: keywordTokenizer

<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" tokenizerFactory="solr.KeywordTokenizerFactory" />

Во всяком случае, этот подход выглядит как хак, и я не могу оценить побочные эффекты (масштабируемость,...) - так что будьте осторожны!