Точное совпадение SOLR над текстом, содержащим точное совпадение

Я не мог найти лучшего титула, я надеюсь изменить его позже, если это возможно, на ваших возможных сайтах.

Моя проблема:

У меня есть база данных с музыкантами. Они выглядят так: "dr.dre feat. Akon", "eminem и dr. Dre", "dr. Dre feat. Ll cool j", "dr. Dre", "dr.dre feat. Eminem и skylar grey", У нас есть только два поля: id и name.

В ядре solr core по умолчанию я запускаю этот запрос: "q = dr. dre", и результаты в порядке, но не идеальны, выглядя так:

  • др. dre feat. Akon
  • eminem и др. Дре
  • др. dre feat. ll cool j
  • др. Дре
  • ...

Обратите внимание, что они получили точный результат.

Я хочу, чтобы в качестве первого результата был "dr.dre", а затем все остальные, например:

  • др. dre < dre в первую очередь
  • eminem и др. Дре
  • др. dre feat. ll cool j
  • др. dre feat. Akon
  • ...

Как мне это достичь? (фильтры, токенизаторы, поля копирования и т.д. не имеет значения. Я не могу изменить код внутри solr, как я видел на каком-то другом форуме)

Спасибо.

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