Поиск продуктов SOLR eDISMAX

Я новичок в SOLR и применяю его для поиска в нашем каталоге продуктов. Я создаю нграммы и пограничные нграммы в полях названия бренда, отображаемого имени и категории.

Я использую edismax и определил qf как displayname_nge displayname_ng category_nge category_ng brandname_nge brandname_ng.

Когда я ищу «витамин С» (без кавычек), я получаю все витамины. Если я окружу это кавычками, то получу только витамин С. Проблема в том, что я не всегда могу заключать строку запроса в кавычки, потому что человек может ввести «жевательный витамин С» или «поставщик x витамин С». Я пробовал параметр мм без везения. Я также пробовал применять разные уровни повышения и все еще не получил ожидаемых результатов.

Любые предложения будут ценны. Спасибо


person whitemtnelf    schedule 15.05.2014    source источник


Ответы (3)


Была ли причина использовать для поиска только поля ngrams? Я не уверен, что это проблема в вашем случае, но вы можете посмотреть конфигурацию анализа ngrams в schema.xml. Один из моих индексов выглядит так:

<fieldType name="ngram" class="solr.TextField" >
<analyzer type="index">        
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
    <tokenizer class="solr.LowerCaseTokenizerFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
</analyzer>
<analyzer type="query">        
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
    <tokenizer class="solr.LowerCaseTokenizerFactory"/>
</analyzer>
</fieldType>

Хотя вы можете видеть, что на самом деле используется более безопасный EdgeNGramFilterFactory, здесь важно отметить minGramSize="2". Это означает, что в процессе индексации будут созданы только граммы, состоящие не менее чем из двух символов. Слово «с»? Это не получает ни грамма на всех. Хотя вы можете установить minGramSize="1" и перестроить свой индекс, односимвольные граммы — очень плохая идея, так как ваш поиск «с» будет соответствовать любому документу со словом, начинающимся с «с» (или содержащим букву «с» с NGramFilterFactory ).

Если вы в настоящее время используете NGrams с minGramSize="2", поиск «ca» найдет любые документы с любыми словами, содержащими буквы «ca» последовательно в этом порядке. Это может быть не совсем то, что вы хотите.

Моим главным предложением было бы отказаться от ngrams в пользу более ванильного текстового поля. Хотите ли вы сохранить edge-ngrams для лучшей поддержки усечения, зависит от вас, но я подозреваю, что вам повезет больше, если поле Text будет хотя бы в миксе.

Вы также можете взглянуть на этот вопрос в StackOverflow: "Могу ли я защитить короткие слова от фильтра n-грамм в Solr?" если вы хотите продолжить изучение n-грамм.

Кроме того, вам следует подумать об использовании встроенного инструмента анализа Solr, чтобы выяснить, где ваши поиски терпят неудачу. Вы выбираете поле или fieldType и предоставляете значения для того, что было введено в индекс и что ищется. Он покажет вам, как анализ работает с обоими значениями, чтобы вы могли увидеть, как разбивается каждая строка и почему она создает или не создает совпадающие токены. URL-адрес инструмента зависит от того, находитесь ли вы в многоядерной среде, но если вы зайдете в веб-интерфейс Solr, вы сможете найти ссылку Analysis слева.

Обновление:

Теперь, когда я получил от вас немного больше подробностей и снова думаю об этом, результаты, которые вы получаете, вполне объяснимы.

С помощью minGramSize="1" при поиске без кавычек по запросу "витамин с" будут найдены записи со словом "витамин" (или более длинным словом, содержащим "витамин") и словом "с" (или более длинным словом, содержащим "с"). Поскольку в большинстве записей где-то есть буква «с», это вряд ли является ограничивающим фактором, и ваши результаты будут очень близки или точно такие же, как ваши результаты только для слова «витамин».

В цитируемом поиске по слову «витамин с» буква «с» теперь должна стоять в слове, непосредственно следующем за витамином, что делает поиск гораздо более полезным, но все же не лучшим. Вы должны быть в состоянии проверить это, найдя записи, в которых есть слово после витамина, которое не является обозначением витамина. Например, запись с упоминанием «таблетки витамина» должна быть найдена при поиске «витамин b» (потому что в слове «таблетки» есть буква «b»). и запись с упоминанием «таблицы витаминов» или «дефицита витамина» должна быть найдена при поиске «витамина с».

В результате я настоятельно рекомендую иметь набор полей для поиска отдельно от ваших полей для автозаполнения. NGrams с minGramSize="1" просто не дадут вам разумных результатов для фактического шага поиска.

person frances    schedule 15.05.2014
comment
Это было сложной проблемой, потому что пользователи хотят, чтобы поиск был очень щадящим, но в то же время точным. Я попытался установить размер ngram равным 2, но это испортило функциональность опережающего ввода. На данный момент я использую регулярное выражение, чтобы заключить витамин в кавычки в моем коде. SOLR 4.8 RegexReplacementFilter будет поддерживать найденные замены групп, поэтому я перенесу его из кода в определение схемы. - person whitemtnelf; 15.05.2014
comment
Прощать, но быть точным — почти универсальная цель. Возможно, вы могли бы использовать другие наборы полей для автозаполнения поисковых запросов, чем те, которые вы используете для предоставления фактических результатов поиска. По сути, это два разных вопроса (что набирает пользователь и какие продукты соответствуют этому запросу). Кроме того, я не уверен, что вам понадобятся NGrams в дополнение к EdgeNGrams для автозаполнения. - person frances; 15.05.2014
comment
Насколько я знаю, minGramSize="1" довольно стандартен для функций автозаполнения, но вы не захотите использовать это поле для своего фактического поискового запроса. - person frances; 15.05.2014
comment
@whitemtnelf Я думаю, что нашел объяснение поведения поиска, которое вы видите, и добавил его в обновлении своего ответа. - person frances; 16.05.2014

Другой вариант - использовать edismax - 'mm', там вы можете указать процент совпадения. если вы дадите 100%, это даст вам точное совпадение. 75% даст вам список витаминов... вы можете программно обрабатывать% в соответствии с вашими потребностями

person BalaE    schedule 09.01.2015

Вы можете заменить ключевое слово запроса следующим образом: «витамин с» витамин с». В таком случае записи, соответствующие «витамину с», могут получить более высокий балл, чем записи, соответствующие «витамину» и «с» по отдельности. Ваши результаты поиска по-прежнему будут возвращать все совпадающие записи. Пожалуйста, посмотрите, поможет ли это, и не стесняйтесь комментировать.

person Sin Ryan    schedule 19.03.2020