Ответ 1
Есть несколько разных способов получить результат "dr.dre" , чтобы он появился первым. Я прошу прощения за длинный ответ, но, как это часто встречается в Solr, ответ зависит от ваших приоритетов и потребностей.
Это, вероятно, избыточно, но я хотел бы начать с того, что вы видите оценки для каждого результата. Ваш вопрос не сделал это совершенно ясным. Когда вы делаете свой запрос, вам нужно явно указать Solr для сортировки результатов в порядке убывания по их оценкам, хотя это можно настроить в
solrconfig.xml
. Я предполагаю, что вы уже это делаете, но чтобы убедиться, вы можете попробовать такой запрос:q="dr. dre"&fl=*,score&sort=score desc
. Это покажет вам рассчитанную оценку для каждого результата и сначала отсортируйте результаты с самыми высокими оценками.
Нормативы
Нормы - это гибкий вариант, который работает с Solr довольно естественно. Поле name
должно, вероятно, иметь значение type
, которое сопоставляется с записью fieldType
. fieldType
должен иметь class="solr.TextField"
, и не должен иметь omitNorms="true"
. Если вы явно не укажете нормы в своем поле имени, Solr рассмотрит, сколько имен соответствует вашим условиям поиска и сколько раз ваши поисковые термины совпадают в имени при вычислении оценки для документа. "dr.dre" будет иметь самый высокий балл, потому что 100% слов в имени соответствуют вашему поиску.
Вы можете прочитать о нормах и ознакомиться с хорошей общей конфигурацией fieldType
на справочной документации по Solr или в вашей загруженной документации Solr для вашей конкретной версии Solr. Преимущество использования норм заключается в том, что в дополнение к тому, что их довольно просто реализовать, они прогрессивные. Таким образом, в то время как "dr.dre" будет наиболее релевантной записью со 100% своего имени, соответствующего вашему поиску, "eminem и dr.dre" также будут более релевантными, чем "весь список парней, а также dr.dre", потому что ваш термин поиска - это большая доля имени.
Точное совпадение
Точное совпадение - сложная проблема в Solr, во многом потому, что существует разная степень точности, и действительно точное соответствие редко бывает желательным в реальной жизни. Например, если ваша запись имеет имя "dr.dre" , "dr dre" (без периода) достаточно близко, чтобы быть точным? "Доктор Дре"? "Dr.dre"?
Если вы решите реализовать точный поиск по совпадению, то вы, вероятно, захотите настроить поле копирования в schema.xml
:
<copyField source="name" dest="exactName"/>
Затем вам нужно будет искать оба поля вместе. Как вы это делаете, зависит от того, какой поисковый парсер вы используете. Если вы используете анализатор запросов standard/lucene, вам нужно будет настроить свои запросы при поиске OR (например, q=name:"dr. dre" OR exactName:"dr. dre"^4
). "^ 4" после поискового запроса делает совпадение в 4 раза важным/релевантным как совпадение в другом месте запроса. Если вы используете анализатор запросов Dismax или Extended Dismax, у вас есть доступ к новому qf
, что позволяет вам предоставить список полей, которые будут использоваться для вашего поиска, и установить некоторые из них более важными, чем другие. Например, qf=exactName^4 name&q="dr. dre"
указывает Solr на проверку "dr.dre" в обоих полях, но считайте, что совпадение в поле exactName должно быть в 4 раза больше, чем в поле имени. (Если это работает для вас, значение по умолчанию qf
может быть установлено в solrconfig.xml
, поэтому его не нужно пересчитывать с каждым запросом.)
Это оставляет неопределенное значение fieldType
в поле exactName. Если вы чувствуете, что будет работать только полностью точное совпадение, а вариации в заглавной или пунктуации делают совпадение неточным, тогда вы можете настроить точное имя в виде строки:
<field name="exactName" type="string" indexed="true" stored="false" multiValued="false"/>
Но, скорее всего, вы захотите разрешить некоторые вариации в том, что считается "точным", и в этом случае вам нужно будет создать новый fieldType
, возможно, используя ключевое слово Tokenizer, который не разбивает точное имя на несколько индексированных токенов, но сохраняет его как единственный токен. Например:
<fieldType name="exactish" class="solr.TextField">
<analyzer>
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
<field name="exactName" type="exactish" indexed="true" stored="false" multiValued="false"/>
Этот очень простой пример включает в себя только токенизатор ключевых слов, чтобы сохранить все имя как один токен, а фильтр нижнего регистра, чтобы убедиться, что разница между верхним и нижним регистром не имеет значения. Если вы хотите, чтобы ваше точное совпадение прощало в любых других условиях, вам нужно будет изменить анализ для fieldType.
Важно:при поиске по строковому полю или текстовому полю, имеющему токен-ключ для ключевых слов, рекомендуется убедиться, что поисковые запросы, которые вы отправляете в Solr, всегда имеют кавычки вокруг них (например, поиск фразы). В противном случае ваш поиск будет разбит на отдельные термины, прежде чем он будет сравниваться с полем, и ни один из ваших условий не будет соответствовать всему индексированному полю. Это может привести к тому, что никогда не найдет совпадений в поле вообще, кроме случаев, когда значения не содержат пробелов. Это не проблема, если вы просто используете Нормы для управления релевантностью в текстовом поле с более стандартной символикой.