Ранжирование фонетических результатов поиска

Я хочу использовать возможности фонетического поиска в спящем поиске. Проблема в том, что точные совпадения не ранжируются в верхней части результатов поиска. Например, поиск "john" возвращает эти результаты:

  • джон
  • Джон
  • Jone

Я бы ожидал, что "Джон" будет указан в верхней части

Я определил свой анализатор следующим образом:

    @AnalyzerDef(name = "phonetic", 
    tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), 
    filters = { 
            @TokenFilterDef(factory = StandardFilterFactory.class), 
            @TokenFilterDef(factory = PhoneticFilterFactory.class, params = {
                @Parameter(name = "encoder", value = "DoubleMetaphone"), 
                @Parameter(name = "inject", value = "true") 
            }) 
    })
@Analyzer(definition = "phonetic")
public class User{
    @Field(index=Index.TOKENIZED, store=Store.YES)
    private String firstname;

    @Field(index=Index.TOKENIZED, store=Store.YES)
    private String lastname;
}

Поиск осуществляется с помощью этого кода:

String[] fields = new String[] { "firstname", "lastname" };
            MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,
                    sf.getAnalyzer("phonetic"));

Было бы здорово, если бы вы могли дать мне любую подсказку / помощь, как вы достигнете этого рейтинга. Я пытался найти что-то через Google, но я только узнал, что это нужно реализовать самостоятельно, используя расширение запроса, чтобы повысить точное соответствие больше, чем результаты фонетического поиска... Большое спасибо заранее за помощь. Я использую Hibernate Search 3.1 вместе с Solr 1.3

Бр, Шейн

3 ответа

Решение

Ваш запрос должен работать так, как вы указали. Поскольку вы указываете inject=true на ваше PhoneticFilterвы должны действительно получить больше терминов для точного совпадения (то есть совпадения как для метафона, так и для совпадения в виде простого текста), и это свидетельствует о моем тестировании.

Проблема, которую я вижу, состоит в том, что ваш анализ оставляет вас с чувствительным к регистру поиском точных совпадений. Если вы индексируете "John" и ищете "john", фонетическое соответствие будет работать просто отлично, но вы пропустите точное соответствие из-за чувствительности к регистру.

Просто добавив LowercaseFilter к вашей цепочке фильтров следует это исправить. Я бы порекомендовал добавить его прямо над вашим PhoneticFilter, лайк:

filters = { 
        @TokenFilterDef(factory = StandardFilterFactory.class), 
        @TokenFilterDef(factory = LowerCaseFilterFactory.class),
        @TokenFilterDef(factory = PhoneticFilterFactory.class, params = {
            @Parameter(name = "encoder", value = "DoubleMetaphone"), 
            @Parameter(name = "inject", value = "true") 
        }) 
}

Расположение над PhoneticFilterFactory поддерживает метафоны в верхнем регистре, что не только следует соглашению, но также гарантирует, что коды метафонов и обычный текст не будут совпадать друг с другом. Не могу вспомнить ни одного случая, когда это было бы проблемой, на самом деле, но все равно кажется хорошим.

Спасибо за ответы, теперь я использовал порядок аннотаций "femtoRgon" и определил несколько анализаторов, используя @Fields (по умолчанию и фонетический), когда я комбинирую запрос со стандартным и один с поиском по фонетическому полю, используя разные загрузочные значения (более 2.0f загрузки по стандарту)

Спасибо всем за помощь

Бр, Шейн

Джон и Джон абсолютно одинаковы с точки зрения фонетического анализатора. Поиск в Hibernate позволяет определять несколько анализаторов, и вы также можете индексировать одно и то же свойство несколько раз, используя множественную аннотацию формы @Fields.

Допустим, вы индексируете firstname в двух полях с именами firstname_phonetic и firstname_standard, затем вы можете создать два экземпляра Query для каждого и объединить два запроса, используя BooleanQuery, с предложением SHOULD. Это позволит партнеру объединить баллы обоих, чтобы точные совпадения оценивались выше.

Другие вопросы по тегам