Comments 6
— коммитом SQL транзакции только после успешной обработки запроса
— второй отдельной транзакцией, подтверждающий переиндексацию.
Elasticsearch — это, можно сказать, порт Lucene. Т.е. имеет все те недостатки, что и Lucene. Потому его и не используют как master database.
Вы в заголовке статьи пишете о fuzzy search, а в самой статье говорите о fulltext-search, являющимся частным случаем первого. Это разные вещи. Пример fuzzy search в Elasticserach — Minimum Should Match. По крайней мере, так я это понимаю :)
Что касается, Вашего вопроса, порт пишется под задачу, не надо искать готового решения. Если Вы не понимаете как это должно работать, лучше не делать…
А так, посмотрите CQRS, Event Sourcing, и лучше, если бы модель для поиска была отлична от первоначальной доменной модели Вашего приложения, в частности, имела бы ограниченное количество полей и индексов. И не забывайте, что вставка/обновление в Lucene и, как следствие в ElasticSearch, чрезвычайно сложная операция ;)
select * from russian where message lucene 'Харбахрб~0.5' limit 2
Пример для h2 я взял напрямую из документации. Для нечеткого поиска там будут тот же синтаксис
SELECT * FROM FTL_SEARCH_DATA('Jonh~0.7', 0, 0);
Согласен, что вставка и обновление в ElasticSearch чрезвычайно сложная операция (за это ее многие и любят). И отсуствие отказоустойчивых «мостов» это наша реальность. (Хотя почти все разработчики таких «мостов» включают эту опцию в «дорожную карту»). Но хотелоь бы иметь попроще и из коробки.
Включение индекса типа lucene в реляционную базу данных может решить вопрос с поиском для сайтов малого и среднего уровня по объему и посещаемости. (а еще и сэкономить деньги на сервер т.к. для ElasticSearch минимальные требования по памяти 16Гб а лучше 32, что на порядок дороже необходимого для среднего сайта 4Гб).
Повторюсь, не ищите простое решение для непростой задачи! Для малого сайта 4Гб Вам хватит, не сомневайтесь!
Что касается, стека МастерДБ + Эластик, то я бы посоветовал акцептить данные в приложении (админке) при их добавлении/изменении/удалении через Event Sourcing. Т.е. определяете метод Accept[Insert/Update/Remove]<TModel>(TModel model)
, который и добавит/изменит/удалит Вашу доменную модель должным образом в индекс эластика со всеми нужными связями. Только этот метод должен быть реализован таким образом, чтобы никакое состояние индекса или мастерДБ не влияло на его результат — результат должен быть всегда одинаков.
Пример:
Добавляем, меняем товары, производителей и категории интернет-магазина.
Делаем два метода:
1) AcceptInsert<Product>(Product product)
: В результате, в индекс добавляется товар с проверкой по полю SourceId (Id в Вашей МастерДБ). У товара производитель (производителей мы редактировать не можем, только добавлять) копируется во вложенный документ, а категория ищется уже в индексе по SourceId.
2) AcceptInsert<Category>(Category category)
: В результате, в индекс добавляется категория с проверкой по полю SourceId.
После сохранения товара в админке, вызываем метод AcceptInsert<Product>
. Либо делаем шедулер, который обновляет индекс каждые n-минут, работая с исходными документами по некоторому фильтру.
Нечеткий поиск (fuzzy search) в реляционных базах данных