Хабы: OpenStreetMap, Геоинформационные сервисы
Введение.
Для логистической компании необходимо иметь геосервис. Геосервис — сервис, выдающий геоточку по адресу, и наоборот, по геоточке определяющий адрес. Все легко и просто, когда поиск делает машина, наименование города, наименование улицы и прочих атрибутов поиска можно указать сколь угодно, и это все приведет у лучшей точности и быстроте. Но все резко меняется, когда поиск начинает делать человек. Человек, используя свой контекст (знания, навыки, привычки), начинает искать настолько свободно, насколько сам свободно мыслит. И это может свести с ума любую машину. Не претендуя на знания в последней инстанции, опишу несколько выразительных этапов, которые прошли мы.
Этап первый. Эластик все сам поймет!
Уверовав в мощь Эластика, мы решили, а пусть эластик сам ищет по строке, содержащий полный адрес. То есть, воспользуемся возможностью полнотекстового поиска Эластика. Сказано — сделано. Создали индекс эластика, причем разбили слова на нграммы, привели все к одному регистру и пр. Сделали микросервис, пробуем. Эластик не подвел, но есть ньюанс:
он, конечно же, находит нужный адрес, но где-то далеко, за пределами двадцати строк, которые комфортно оценивать человеку. Начинает сказываться порядок записи данных в индекс, сколько раз повторяются слова и прочее, и прочее. Самый простой вариант причины: это при поиске улицы выдаются еще и дома, а их много…. Так дело не пойдет.
Этап второй. Все мы из реляционных баз данных.
Раз не получается точно искать полнотекстовым поиском, то нужно данные структурировать! Решили структурировать так, выбрать основные атрибуты адреса: наименование города, наименование улицы, номер дома. Это основные структуры, которые должны быть в любом адресе(хотя и не всегда, есть поселки, где нет улиц!). Сделали новую структуру индекса в эластике. Но появилась проблема: адрес приходит единой строкой. Где в ней город, улица, дом? Все легко решается если пользователь указывает якоря: г. или город, ул. или улица и т. д. Хотя и тут вариантов различных якорей — масса(только по языкам сколько). Вариант с якорями хорошо работает, эластик ищет быстро и точно. Но если пользователь не указывает якоря? Сделали предположение что пользователь вводит сначала город, потом улицу, потом дом. То есть считаем что город пользователь точно ввел. Пробуем и вроде работает, но как-то не уверенно, то ищет, то нет. И проявилась проблема двойных названий: Нижний Новгород, Верхний Уфалей, Третья Улица Строителей.
Читать далее