Арсений Максимов
30 марта 2017
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Василий, привет!

Расскажи про устройство поиска в ваших книгах? В чём и как храните данные? Как показываете превьюшки текста в поиске? Что почитать на эту тему? Как дела?


Под капотом у поиска Sphinx, Thinking Sphinx и PostgreSQL.

Книга — ХТМЛ-документ. Чтобы поиск знал, какой текст на каком развороте, мы парсим книгу, разбираем её по разворотам и сохраняем в PostgreSQL для последующей индексации.

Во время парсинга вытаскиваем и очищаем текст разворота:

  • выкидываем текст шмуцтитулов;
  • выкидываем служебные элементы: номера страниц, модули-дублеры и элементы с классом no__index;
  • экранируем инициалы (А. Г.) и сокращения (т. е., т. п.), чтобы не считать их границей предложения в результатах поиска.

Когда текст готов, Sphinx разбивает его на слова. Чтобы поиск учитывал словоформы и находил по запросу «книга» и «книгу», и «книги», Sphinx «нормализует» слова перед тем, как положить их в индекс. За это отвечают морфологические алгоритмы. Как правило, используют лемматизаторы или стеммеры.

Лемматизатор строит нормальную форму слова по словарю. Если не находит, додумывает форму по аналогии. Стеммер извлекает неизменяемую часть слова по правилам удаления суффиксов и окончаний:

ЛемматизаторСтеммер
девушек девушка девушек
редьюсером редьюсерый, редьюсер редьюсер
кружек кружка кружек
макосью макосие макос
боязненных боязнить, боязненный боязнен

Книжный поиск использует лемматизатор (morphology = lemmatize_ru_all), потому что он чаще выдает правильную форму. И, конечно, мы индексируем изначальную форму слова для поиска точных совпадений (index_exact_words = 1).

Когда читатель ищет в книге «прямоугольники», запрос уходит к бэкенду. Бэкенд обращается к Sphinx за выдержками результатов поиска (buildExcerpts) и возможными словоформами. Sphinx нормализует запрос: ищет совпадения с «прямоугольник» и «прямоугольники».

Чтобы в выдаче были предложения целиком, а не какая-то случайная часть окружающего текста, Sphinx настроен так, чтобы считать границей выдержки предложение (passage_boundary = sentence).

Результат поиска в JSON:

[  
  {  
    "number":6,
    "quotes":[  
      "Глав­ное изоб­ре­те­ние чело­века — не коле­со,
       а <span class=\"match\">пря­мо­уголь­ник</span>.",
      "А <span class=\"match\">пря­мо­уголь­ник</span> в при­ро­де встре­ча­ет­ся редко."
    ],
    "matches":[  
      "пря­мо­уголь­ник",
      "пря­мо­уголь­ни­ки",
      "Прямо­уголь­ник",
      "пря­мо­уголь­ни­ков",
    ]
  },
  // ....
]

quotes — предложения-выдержки из текста. matches — словоформы, встречающиеся на развороте. Мы используем их, чтобы подсвечивать совпадения:

Подсветка плавно исчезнет спустя 4 секунды, если поскроллить разворот

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

По полнотекстовому поиску советую почитать и посмотреть:

Чтобы знать, что могут другие движки полнотекстового поиска, и выбирать лучший инструмент для задачи, советую почитать и посмотреть:

Про превьюшки разворотов в результатах поиска — в следующем совете.

P. S. Это был совет о веб-разработке. Хотите знать всё о коде, тестах, фронтенд-разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Поделиться

Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

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

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.





Недавно всплыло

Кто ты? 1 2 2 Расскажите об управляемости: программа 2