Введення

Пошук записів є загальною вимогою для веб-додатків. Як правило, для більшості з них ставиться вимога, щоб користувачі могли швидко отримати доступ до даних великий записи, які їм потрібні.

Хоча це цілком можна зробити, використовуючи прості запити SQL, іноді більш ефективно використовувати пошуковий движок.

Solr є найпопулярнішою пошуковою платформою проекту Apache Lucene. Її основні можливості включають потужний повнотекстовий пошук, підсвічування виявлених фрагментів співпадінь, пошук за повним збігом, індексацію, близьку до реального часу, динамічну кластеризацію, інтеграцію баз даних, різноманітну обробку документів і геоориентированный пошук.

У цій статті ми розглянемо виконання повнотекстового пошуку з допомогою Sunspot, бібліотеки, дозволяє інтегрувати Solr в інші додатки.

Що ви будете створювати:

Налаштування проекту

Я створила просте додаток на Github, що буду використовувати, замість того, щоб починати з нового проекту.

Додаток виводить список товарів з назвою, зображенням, ціною і описом продукту.

Я вже додала деякі вихідні дані, так що ви можете запускати rake db:seed, якщо самі не хочете вводити дані.

Додаток використовує Paperclip для вкладених зображень, і, оскільки я використовую зміна розмірів зображень, на вашій системі повинен бути встановлений ImageMagick. На комп’ютері має бути встановлена Java Runtime.

На малюнку нижче показано сам додаток. У формі пошуку зверху в даний момент нічого не задано, але ми надамо користувачеві можливість шукати продукти і отримувати результати, засновані не тільки на назві продукту, але і на його описі:

Повнотекстовий пошук у Rails

Пошук

Ми почнемо з включення джемів Sunspot і Solr в Gemfile. Для розробки ми будемо використовувати джем sunspot_solr, який міститься в дистрибутиві Solr, тому нам не потрібно буде встановлювати його окремо:

gem ‘sunspot_rails’
group :development do
gem ‘sunspot_solr’
end

Запустіть bundle install, а потім запустіть наступну команду, щоб згенерувати файл конфігурації Sunspot:

rails generate sunspot_rails:install

Ця команда створює файл /config/sunspot.yml, в якому вашому додатку вказується, де знайти сервер Solr.

Щоб налаштувати об’єкти, які ви хочете проіндексувати, додайте до об’єктів пошуковий блок. У стартовому проекті, у нас є модель Product з такими полями: назва, ціна, опис та фото. Ми дозволяємо пошук повного тексту за значеннями полів назви і опису.

У файл /models/product.rb додаємо:

searchable do
text :name, :description
end

Запустіть сервер Solr, виконавши команду:

rake sunspot:solr:start

Sunspot індексує нові записи, які ви створюєте, але якщо у вас до цього вже існували в базі даних деякі записи, запустіть rake sunspot:reindex, щоб вони також були проіндексовані.

Потім ми додаємо код в контролер продуктів, який приймає вводите в рядок пошуку дані і передає їх у пошуковий движок. У наведеному нижче коді ми викликаємо search в моделі Product і передаємо в блок.

Потім викликаємо в блоці метод fulltext і передаємо рядок запиту, за якою ми хочемо провести пошук. Є кілька методів, які ми можемо тут використовувати, щоб нам отримати потрібні результати пошуку.

Результати пошуку потім привласнюються об’єктам @products, які будуть виведені:

def index
@query = Product.search do
fulltext params[:search]
end
@products = @query.results
end

Запустіть програму, в даний момент можете здійснити пошук з доступних продуктів.

Solr зробить пошук по назвах продуктів і описами без урахування регістру, використовуючи як аргумент введене вами слово або фразу. Ви можете задати для одного поля більшу значимість при пошуку, щоб поліпшити релевантність результатів пошуку.

Це робиться за допомогою методу boost, який передає значення, що визначає пріоритет, який призначається різних полів. Поля з найбільшим значенням буде мати найбільшу значимість при пошуку.

У нашому додатку ми можемо встановити, щоб продукти, які містять шуканий рядок у назві, виводилися вище.

Це робиться через внесення наступних змін в файл /models/product.rb:

searchable do
text :name, :boost => 2
text :description
end

Переиндексируйте запису, виконавши rake sunspot:reindex, і тепер результати з шуканої фрази в назві продукту, будуть виводитися вище тих, що містять ту ж фразу в описі. Щоб перевірити це, ви можете додати більше записів в базу.

Сегментований перегляд

Сегментований перегляд є способом навігації по результатах пошуку за допомогою різних наборів супутніх атрибутів.

Наприклад, в нашому додатку ми можемо класифікувати знайдені продукти за ціною і визначати кількість продуктів, що належать до кожного цінового діапазону.

Спочатку додайте ціну метод searchable файлу /models/product.rb:

searchable do
text :name, :boost => 2
text :description
double :price
end

Потім викличте в контролері facet. Продукти будуть розбиті на діапазони за ціною з інтервалом в $100.00. Тут ми припускаємо, що всі продукти коштують менше, ніж $ 500:

def index
@query = Product.search do
fulltext params[:search]
facet :price, :range => 0..500, :range_interval => 100
with(:price, Range.new(*params[:price_range].split(«..»).map(&:to_i))) if params[:price_range].present?
end
@products = @query.results
end

У файлі перегляду вставте наступний код в те місце, де ви хочете бачити сегментовані результати:

Результати пошуку

  • row.value, :search => params[:search] %> ()
    ( nil %>)

Тепер при пошуку вам буде виводитися список сегментів, що показує, скільки результатів пошуку міститься в кожному ціновому діапазоні.

У нашому прикладі додатка, якщо ви ставите на пошук слово ‘camera’, ви побачите наступний список:

100.0..200.0 (2)
200.0..300.0 (1)
300.0..400.0 (1)

Кожен елемент списку являє собою посилання, при натисканні на нього ви отримаєте список продуктів, які відповідають умовам пошуку, а також потрапляють в ціновий діапазон, який ви обрали.

Посилання передає оригінальний пошуковий запит і вибраний діапазон індексне дію. Оскільки діапазон передається у вигляді рядка, ми використовуємо Range.new(*params[:price_range].split(«..»).map(&:to_i)), щоб перетворити його назад в діапазон.

Ви можете використовувати умовні оператори для виведення більш коректних посилань, наприклад, $100 — $199 (2) замість 100.0..200.0 (2), але тут ми не будемо вдаватися глибше в цю тему.

Додаткові налаштування

Є ще ряд налаштувань, які можна зробити, щоб налаштувати роботу Solr. За замовчуванням Sunspot виконує пошук повного тексту шляхом ділення рядка пошуку на токени на основі пробілів та інших розділових символів за допомогою смарт-токенайзера StandardTokenizer.

Всі токени приводяться до нижнього регістра, і на пошук задається точну відповідність.

У ряді випадків це може бути корисно, але ви також можете налаштувати пошуковий движок таким чином, щоб враховувати фактор людської помилки при написанні або дозволити враховувати не суворе відповідність.

Наприклад, ви можете задати в параметрах движка деякі синоніми.

Тоді користувачі, які вводять текст, не строго відповідний записами в базі даних, все ж зможуть знайти схожі результати. Наприклад, у записах може міститися слово ‘ipod’.

Ви можете надати для нього синоніми, такі як ‘iPod’, ‘i-pod’ і ‘i pod’, щоб збільшити шанси користувача знайти потрібний запис.

Ще одна корисна функція — це можливість додати похідні, що дозволить Solr знаходити різні слова з тим самим коренем. Наприклад, якщо користувач ввів ‘run’, він отримає результати зі словами ‘run’ і ‘running’. Або, якщо він шукав ‘walk’, результати будуть включені дані, які містять ‘walk’, ‘walking’, ‘walked’ і так далі.

Налаштування Solr містяться у файлі solr/conf/schema.xml. Через внесення змін у цей файл ви можете налаштувати конфігурацію сервера.

Це виходить за межі цієї статті, проте більш детально з цією темою ви можете ознайомитися в статті розширеної конфігурації повнотекстового пошуку і на Solr wiki.

Висновок

Тепер, щоб зупинити сервер Solr, виконайте:

rake sunspot:solr:stop

Ми розглянули, як використовувати джеми Sunspot, щоб задіяти пошуковий движок Solr в додатку Rails. Крім налаштувань, які ми використовували, є ще багато інших опцій, які ви можете задіяти для конфігурації пошуку.

Не забудьте ознайомитися з файлом опису для отримання більш детальної інформації.

Solr надає вам можливості пошуку, яких важко досягти за допомогою стандартних запитів SQL. Для простих додатків, з невеликою кількістю записів в базі даних запити SQL можуть вирішувати поставлені завдання.

Але якщо ви хочете знайти що-то з більш гнучкою настройкою, то варто розглянути Solr або інші доступні пошукові сервери.

Переклад статті «Full Text Search in Rails» був підготовлений дружною командою проекту Сайтостроение від А до Я.