Ранжирование фонетических результатов поиска
Я хочу использовать возможности фонетического поиска в спящем поиске. Проблема в том, что точные совпадения не ранжируются в верхней части результатов поиска. Например, поиск "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. Это позволит партнеру объединить баллы обоих, чтобы точные совпадения оценивались выше.