Привет, Хабр! Меня зовут Алексей Кокухин, я бэкенд-разработчик в Friflex. Мы создаем сайты и мобильные приложения и специализируемся на решениях для ритейла. Для наших клиентов конверсия в покупку — значимая метрика, поэтому мы постоянно изучаем, какие факторы на нее влияют.
Часто пользователи уходят просто потому, что поиск не смог распознать их запрос. По статистике Baymard Institute, проблемы с распознаванием поисковых запросов есть почти у каждого второго онлайн-магазина. В этой статье предлагаю разобраться, как настроить поиск мобильного приложения, чтобы он распознавал два самых популярных вида запроса — точные и ошибочные.
Точный запрос
Когда пользователь точно знает, что ищет, он вводит точный запрос. Например, «чипсы Lay’s». Точный запрос — самый легкий вариант с технической точки зрения. Распознавать его помогает полнотекстовой поиск.
Полнотекстовой поиск индексирует все слова и фразы, которые встречаются в приложении. Индекс содержит информацию о том, где встречаются эти слова и фразы, и определяет их вес или релевантность.
Когда пользователь пишет в поиске «чипсы Lay’s», поиск разбивает запрос на «чипсы» и «Lay’s», ищет эти слова по индексам и находит все документы, где они встречаются. Например, карточку товара «чипсы Lay’s сметана и зелень», новость «Попробуйте чипсы Lay’s со вкусом малосольных огурчиков» и статью «5 рецептов с чипсами Lays».
Система ранжирует документы и отображает пользователю самые релевантные. На первом месте будет карточка товара «чипсы Lay’s сметана и зелень»: в ней больше всего слов из запроса, и они находятся в заголовке и описании продукта.
Настроить полнотекстовой поиск позволяют разные инструменты. Мы чаще всего пользуемся Elasticsearch и Diginetica. Diginetica — это сервис для поиска в интернет-магазинах. Он сам обрабатывает все запросы. Elasticsearch мы настраиваем вручную. Поэтому примеры рассмотрим с ним.
Полнотекстовой поиск
Если вы, как и я, пишете на Ruby, чтобы работать с Elasticsearch
, нужно будет установить библиотеку Elasticsearch gem
.
Затем создаем клиент Elasticsearch, который подключается к Elasticsearch
на localhost:9200
:
require 'elasticsearch'
client = Elasticsearch::Client.new(url: 'http://localhost:9200')
Создаем индекс с именем products
:
client.indices.create(index: 'products')
Добавляем в документ в индекс products
с ID 1:
client.index(index: 'products', id: 1, body: {
name: 'Чипсы Lay’s',
description: 'Вкусные и хрустящие чипсы со вкусом сметаны и зелени.'
})
И ищем по тексту документы, где поле name содержит текст «чипсы Lay’s»:
response = client.search(index: 'products',
body: {
query: {
match: {
name: 'чипсы Lay’s'
}
}
}
)
или
response = client.search(q: 'чипсы Lay’s')
Извлекаем результаты поиска, перебираем результаты и выводим имя каждого документа:
results = response['hits']['hits']
results.each do |result|
puts result['_source']['name']
end
Можно использовать и другие операторы поиска. Например, AND, OR
и NOT
. Чтобы сузить результаты поиска, применяйте фильтры.
Запрос с ошибкой или опечаткой
На самом деле, запрос с ошибкой или опечаткой — тоже вариант точного запроса. Пользователь вводит тип товара, его название или бренд, но неправильно. Например, «чипсы Lays», «чиспы Lay’s» или даже «xbgcs Lay’s». Baymard Institute говорит, что 42% онлайн-магазинов такие запросы не распознают. А значит, рискуют потерять клиентов, которые думают, что товар закончился.
Научить поиск понимать запросы с ошибками можно разными способами. Например, можно интегрировать в систему библиотеки или модули автоматического исправления. Или создать собственный словарь с самыми распространенными ошибками и опечатками. Или использовать фонетический поиск.
Библиотеки и модули автоисправления
В Elasticsearch
есть встроенная функция Elasticsearch Suggester
. Она помогает распознавать запросы, даже если пользователи пишут их неправильно, предлагает варианты исправления и проверяет орфографию. Suggester
просто настраивается и масштабируется вместе с Elasticsearch
.
Но по функциональности эта функция не может сравниться с некоторыми другими библиотеками и модулями автоисправления. Например, Hunspell
или Peter Norvig’s Spelling Corrector
.
Hunspell — это библиотека проверки орфографии с открытым исходным кодом. Ее можно добавить в Elasticsearch
в качестве токенизатора. Кроме того, есть плагины Elasticsearch, которые тоже позволяют интегрировать Hunspell.
Peter Norvig's Spelling Corrector — это алгоритм исправления ошибок, основанный на теории вероятности и расстоянии редактирования — количестве вставок, удалений или замен, необходимых, чтобы преобразовать одно слово в другое. Чтобы интегрировать Peter Norvig's Spelling Corrector
с Elasticsearch
, можно также использовать плагины.
Собственный словарь ошибок и опечаток
Свой словарь частых ошибок и опечаток помогает улучшить распознавание запросов с ошибками, повысить точность поиска и улучшить пользовательский опыт. Создать такой словарь в Elasticsearch
можно разными способами. Например, с помощью Ruby-скрипта.
Для начала создадим Ruby-скрипт и загрузим данные, которые будем использовать для создания словаря. Данные могут быть в виде текстового файла, CSV-файла или JSON-файла. В нашем примере используем такой JSON-файл:
"{\"words\":[{\"word\":\"привет\",\"error\":\"превед\"},{\"word\":\"хлеб\",\"error\":\"пиво\"},{\"word\":\"медведь\",\"error\":\"медвед\"}]}"
# Подключение к Elasticsearch
client = Elasticsearch::Client.new(url: 'http://localhost:9200')
# Подключение к Elasticsearch
client = Elasticsearch::Client.new(url: 'http://localhost:9200')
# Загрузка данных из JSON-файла
data = JSON.parse(File.read('data.json'))
# Создание словаря
dictionary = {}
data['words'].each do |object|
dictionary[object['error']] = object['word']
end
# Индексация словаря в Elasticsearch
client.index(index: 'dictionary', type: 'word', body: dictionary)
# Сообщаем о завершении работы скрипта
puts "Словарь успешно создан!"
Запускаем скрипт:
ruby script.rb
Потом в словарь можно добавлять разные функции. Например, чтобы удалять дубликаты.
Фонетический поиск
У фонетического поиска могут быть разные алгоритмы. Например, Soundex
, Metaphone
, Double Metaphone
и NYSIIS
. Все они преобразуют слова в коды, которые основаны на их звучании. Это помогает обрабатывать запросы с ошибками.
Чтобы настроить фонетический поиск в Elasticsearch
, создайте индекс Elasticsearch
и добавьте поле для фонетического представления слов. Используйте анализатор Elasticsearch «phonetic»
, чтобы преобразовать слова в фонетическое представление.
# Подключение к Elasticsearch
client = Elasticsearch::Client.new(url: 'http://localhost:9200')
# Создаем индекс
client.indices
.create(index: 'my_index',
body: {
mappings: {
properties: {
name: {
type: 'text',
analyzer: 'phonetic'
}
}
}
})
Затем индексируйте данные с фонетическим представлением слов.
# Индексируем данные
client.index(index: 'my_index',
type: 'doc',
id: 1,
body: { name: 'чипсы лейс' })
Теперь используем фонетический поиск Elasticsearch
, чтобы найти «чипсы Lay’s» по запросу «чипсы лейс».
# Поиск
response = client.search(index: 'my_index',
body: {
query: {
match: {
name: {
query: 'чипсы лейс',
fuzziness: 'AUTO'
}
}
}
})
puts response['hits']['hits'][0]['_source']['name']
Результат: чипсы Lay's
Кроме точных и ошибочных запросов есть и другие: запросы по характеристикам, по совместимости или сленговые запросы. Если интересно, я расскажу про них подробнее в следующей статье. Надеюсь, что эта вам понравилась.
P.S. Мы ведем дружелюбный канал про Flutter в Telegram. Присоединяйтесь!