Задача стоит следующим образом. Есть в базе данных таблица терминов. Порядка 100 000 терминов. Много терминов состоят из двух и более слов. Например, "хлорид натрия".
Система примерно раз в час в бизнес-время добавляет новые документы в базу данных (каждый документ порядка 100 слов). При сохранении документа в базу данных нужно все термины в документе автоматически обрамить некоторым тегом, содержащим в атрибуте тэга идентификатор термина из таблицы терминов
Вопрос: как это сделать?
Делаем это для веб-сайта. В дальнейшем при отображении документа на веб-странице все термины должны преобразоваться на лету во вью-слое в ссылки на страницу термина.
Используемые технологии: база данных Postgres, также используем поисковый движок Lucene, возможно, его тоже можно как-то применить к этой задаче.
Рассмотренные нами варианты решения: 1) Простой:
Разбить входящий документ на слова, и для каждого слова находить его вхождение в таблицу терминов. Если нашел, обрамлять слово тегом. Вариант плох тем, что не учитывается морфология.
2) Учет морфологии:
К примеру, есть слово в документе "аллюминием". Для таких случаев думали модифицировать вариант из пункта 1 тем, что взять какую-то морфологическую библиотеку, найти для каждого слова именительный падеж (в данном случае "аллюминий"), и искать в таблице терминов по именительному падежу. Но тут есть проблема, что морфология может плохо работать для специальных терминов. Например, таких как "магальдрат". Я не знаю, как работают технологии морфологического разбора, но если они работают через словарь, то вряд-ли в словаре есть такие специальные термины. Поэтому если где-то будет в тексте слово "магальдратами", то не факт, что морфологией правильно будет найден именительный падеж.
3) Составные термины:
Допустим даже, если нашли даже библиотеку морфологии. Всплывает следующая проблема. Как быть с составными терминами? Например, тот же "хлорид натрия". Если там еще и он используется в каком-то падеже. Например, в тексте встречается "хлоридом натрия". Тут, во-первых, в именительном падеже это будет "хлорид натрий", а в таблице терминов это "хлорид натрия". Уже не совпадает. А во-вторых, уже не получится в исходном документе делать цикл по одному слову, так как термины бывают многословные.
4) Обратный проход:
Поэтому рисуется здесь обратное решение. Идти по всем 100 000 значениям таблицы терминов, и проверять вхождение каждого из них в документ. Это похоже на правильное решение. Но как быть тогда снова-таки с морфологией? Ведь в таблице терминов все в именительном падеже, а в документе в любом падеже.
Я уверен, что задача решаема. Ведь гугл ищет же комбинации слов с учетом морфологии. Подозреваю, что Lucen'ом можно будет эту задачу также решить.
Вопрос производительности здесь не критичный — возможна задержка в обработке документа хоть в несколько часов. Главное, чтобы тяжелая по ресурсам обработка не мешала жить основной части системы. Новые документы будут появляться примерно раз в час. Понятно, что для производительности лучше будет написать хранимую процедуру в БД, но можно ли морфологию использовать из хранимых процедур?
Вопрос точности тоже не критичный. Допускается пропуск некоторых слов, которые могли бы быть ссылкой. 80% терминов ссылками — это отличный результат.
Вобщем, подскажите, пожалуйста, как правильно разработать такое решение?