Наконец-то собрался и написал очередную статью из этого цикла. Теперь я расскажу о том, как сделать хороший полнотекстовый поиск на русском языке для Drupal на Apache Solr.
- Поиск на Drupal 7 с помощью Apache Solr ч.1 — базовая настройка
- Поиск на Drupal 7 с помощью Apache Solr ч.2 — учимся настраивать индекс
- Поиск на Drupal 7 с помощью Apache Solr ч.3 — учимся добавлять собственные поля и опции в индекс
- Поиск на Drupal 7 с помощью Apache Solr ч.4 — фасетные фильтры
- Поиск на Drupal 7 с помощью Apache Solr ч.5 — виджеты для фасетных фильтров
- Поиск на Drupal 7 с помощью Apache Solr ч.6 — настраиваем apache solr + tomcat
- Поиск на Drupal 7 с помощью Apache Solr ч.7 — полнотекстовый поиск на русском языке
В принципе этот материал применим к любому языку, но по понятным причинам я выбрал русский. В конце первой статьи из этого цикла, я писал о том, как улучшить поиск на русском языке. Этот способ простой, но не очень действенный. Максимум на что он способен по умолчанию, это работать с окончанием слова. Рассмотрим простой пример. Слово «климатических» находится по слову климатический.
Но уже для слова климат результатов не будет.
Для того, чтобы сделать поиск более гибким, подключим дополнительный словарь. Я использовал класс HunspellStemFilterFactory для стемминга.
Скачиваем словари для русского языка отсюда — download.services.openoffice.org/files/contrib/dictionaries/ru_RU-pack.zip
Нам нужны два файла — ru_RU.aff и ru_RU.dic. Их необходимо сконвертировать в utf-8, иначе apache solr не будет с ними работать.
Изначально я пытался поменять им кодировку через iconv, но solr с ними так и не заработал.
В итоге я пересохранил файлы в UTF-8 через Krusader — после этого все работало отлично.
После того как вы сконвертируете файлы, их нужно положить в ту же папку солра, где лежит schema.xml
Теперь в схеме (schema.xml) указываем, что мы собираемся использовать HunspellStemFilterFactory и наши словари:
<filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />
<fieldType name="text" class="solr.TextField" indexed="true" stored="true" multiValued="true" positionIncrementGap="100">
<analyzer type="index">
...
<filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />
...
<analyzer type="query">
...
<filter class="solr.HunspellStemFilterFactory" dictionary="ru_RU.dic" affix="ru_RU.aff" ignoreCase="true" />
...
Помимо этого после определения HunspellStemFilterFactory в анализаторе для индекса добавим настройки для того, чтобы разбивать слова на части (граммы). Это сделает поиск более гибким
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" side="front" />
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="25" side="back" />
Если у вас был включен фильтр Портера
<filter class="solr.SnowballPorterFilterFactory" language="Russian" protected="protwords.txt"/>
не забудьте его закоментировать.
Теперь перезагружаем солр и переиндексируем контент. Можно увидеть, что поиск работает намного лучше! Вот пара примеров:
Тоже самое можно делать и со словарями других языков. Полный список словарей — download.services.openoffice.org/files/contrib/dictionaries
Помимо того, чтобы просто использовать готовые словари, вы можете также создать свое правило.
Я заметил, что в русском словаре для солра, нет слова «вомбат» и решил его добавить. Для этого сперва заходим в файл ru_RU.aff и ищем подходящее окончание. Слово «вомбат» имеет нулевое окончание и ему подходит следующее правило:
SFX K 0 а [^ейоь]
SFX K 0 у [^ейоь]
SFX K 0 ом [^ежйоцчшщь]
SFX K 0 е [^ейоь]
SFX K 0 ы [^гежйкохчшщь]
SFX K 0 и [гжкхчшщ]
SFX K 0 ей [жчшщ]
SFX K 0 ов [^ежйоцчшщь]
SFX K 0 ам [^ейоь]
SFX K 0 ами [^ейоь]
SFX K 0 ах [^ейоь]
вомбатА, вомбатУ… вомбатАХ.
Код этого окончания — K.
Теперь открываем файл ru_RU.dic и добавляем новое слово с соответствующим кодом
Код будет описывать каким образом изменяется слово. Разумеется на скриншоте лишь пример и следовало бы вставлять новое слово в алфавитном порядке.
Перезагружаем солр, переиндексируем контент и смотрим результаты
Напоминаю что я использую apachesolr 3.6.1 (это не принципиально, но я сталкивался с тем, что на некоторых версиях иногда не работает то или иное, зачастую проблема кроется в особенностях построения запросов к солру через search api либо в описании schema.xml и config.xml).
На всякий случай прикрепляю свою схему, если у вас что то не получается, попробуйте использовать ее.