2013-11-15 3 views
2

У меня возникла проблема с результатом solr, и я подумал, что попрошу предложения здесь.Solr phonetic matching vs real text field

Я включил фонетическое соответствие, включив <filter class="solr.PhoneticFilterFactory" encoder="RefinedSoundex" inject="true"/> как на уровне запросов, так и на уровне индекса, а также с кодировщиком DoubleMetaphone в качестве варианта.

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

Пример:

В моем индексе, у меня есть документ с поля под названием «имя» и значение «Modenine», когда я искать name:mod, я получаю «Modenine», который в порядке,

Но когда я ищу, используя name:mode, обратите внимание на дополнительный 'e', он возвращает 'Something Foul Mouth', и это потому, что mouth phonetically соответствует mode, я не против иметь «Something Foul Mouth», но я также хочу видеть «Modenine» с mode - это реальный поисковый запрос.

Быстрое решение, которое приходит мне в голову, позволяет добавить фонетический код для индексации во время индексации, а затем использовать утилизацию для ранжирования результата путем предоставления оценки, например, с помощью^2.0.

У меня есть следующее: объявления полого

<field name="phoneticName" type="phonetics" indexed="true" stored="true"/> 
<field name="name" type="phonetics" indexed="true" stored="true"/> 

FieldType для фонетики

<fieldType name="phonetics" class="solr.TextField" positionIncrementGap="100" multiValued="true"> 
    <analyzer type="index"> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" /> 
     <filter class="solr.PhoneticFilterFactory" encoder="RefinedSoundex" inject="true"/> 
    </analyzer> 
    <analyzer type="query">    
     <tokenizer class="solr.WhitespaceTokenizerFactory"/>   
     <filter class="solr.LowerCaseFilterFactory"/> 
     <filter class="solr.PhoneticFilterFactory" encoder="RefinedSoundex" inject="true"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />  
     <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>    
    </analyzer> 
</fieldType> 

Но после повторной индексации, поле phoneticName только имеет точное значение поля имени, это Безразлично Храните фонетический код, который я пытаюсь найти.

Я нашел это solr-boosting-down-phonetic-variations, но не так много деталей.

Благодаря P

ответ

3

Я, наконец, получил его, чтобы работать, когда я ввожу mod в качестве запроса, я получаю около 5 связанных результатов, включая modenine. Как мне удалось это сделать, это использовать фильтр Ngram, который не является тем, что я только что узнал. Фактически, у меня был фильтр Ngram, добавленный в список фильтров в schema.xml с самого начала, но никогда не работал должным образом.

Ошибка в том, что я применяю NgramFilter как на уровне index, так и на уровне query уровня/фазы. Ngram следует добавлять только на этапе index. После удаления фильтра Ngram на этапе запроса мне был нужен результат.

См. Конфигурацию ниже, Обратите внимание, как я добавил: solr.RemoveDuplicatesTokenFilterFactory для удаления возможных дубликатов фильтров NGramFilterFactory.

<fieldType name="phonetics" class="solr.TextField" positionIncrementGap="100" multiValued="true"> 
    <analyzer type="index">   
     <filter class="solr.TrimFilterFactory"/>   
     <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="1000" /> 
     <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="1000" /> 
     <filter class="solr.WordDelimiterFilterFactory" splitOnCaseChange="1" splitOnNumerics="0" 
     generateWordParts="1" stemEnglishPossessive="0" generateNumberParts="0" 
     catenateWords="1" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <tokenizer class="solr.WhitespaceTokenizerFactory"/>   
     <filter class="solr.DoubleMetaphoneFilterFactory" inject="true"/> 
     <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
    </analyzer> 
    <analyzer type="query">  
     <filter class="solr.TrimFilterFactory"/>   
     <filter class="solr.WordDelimiterFilterFactory" splitOnCaseChange="1" splitOnNumerics="0" 
     generateWordParts="1" stemEnglishPossessive="0" generateNumberParts="0" 
     catenateWords="1" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/>   
     <tokenizer class="solr.WhitespaceTokenizerFactory"/>   
     <filter class="solr.LowerCaseFilterFactory"/>  
     <filter class="solr.DoubleMetaphoneFilterFactory" inject="true"/> 
    </analyzer> 
</fieldType> 

Приветствия

Babajide

+0

Другим способом достижения этого без использования NgramFilter, поскольку анализ влияет на время индексирования, заключается в том, чтобы на самом деле одновременно выполнять подстановочные и фонетические соответствия. например (имя: mod *^10.0 ИЛИ имя: mode^2.0) И другие поля, если требуется. Вы также можете добавить имя OR: mod ~^1.0 для ближайшего фонетического соответствия. Это также хорошо помогло мне. Помните, что имя должно быть типа phonetics в объявлении поля для имени. «^» - для подсчета очков. Приветствия Бабаджиде P –

1

Вы не получаете подстановочные матчей, потому что вы не выполняете поиск по шаблону. name:mode* будет соответствовать «modenine», хотя он не будет соответствовать фонетически, поскольку подстановочные/префиксные поиски не анализируются, что имеет смысл, поскольку фонетические алгоритмы работают в предположении, что они работают с полным словом.

Если вы хотите выполнить поиск по обоим, вы должны использовать запрос: name:mode name:mode*.

+0

Благодаря @femtoRgon, я думал, что я где-то читал, что повторение поля дважды не допускается и может привести к странным поведением. У меня есть другое решение для этого, которое я опубликую сейчас, но мне все равно хочется попробовать имя: mode name: mode *, чтобы увидеть результат. Отчитается. –

+0

Возможно, вы имеете в виду проблемы с подсчетом. Несколько повторений поля могут привести к тому, что термин будет более взвешенным, чем вы хотели бы, и в этом случае вы можете использовать 'DisjunctionMaxQuery' для решения этой проблемы. Независимо от того, нужно это или нет, зависит от ваших потребностей, но я не думаю, что в этом случае требуется запрос на утечку. – femtoRgon