|
|
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
Всем привет! Задача стоит следующим образом. Есть в базе данных таблица терминов. Порядка 100 000 терминов. Много терминов состоят из двух и более слов. Например, "хлорид натрия". Система примерно раз в час в бизнес-время добавляет новые документы в базу данных (каждый документ порядка 100 слов). При сохранении документа в базу данных нужно все термины в документе автоматически обрамить некоторым тегом, содержащим в атрибуте тэга идентификатор термина из таблицы терминов Вопрос: как это сделать? Делаем это для веб-сайта. В дальнейшем при отображении документа на веб-странице все термины должны преобразоваться на лету во вью-слое в ссылки на страницу термина. Используемые технологии: база данных Postgres, также используем поисковый движок Lucene, возможно, его тоже можно как-то применить к этой задаче. Рассмотренные нами варианты решения: 1) Простой: Разбить входящий документ на слова, и для каждого слова находить его вхождение в таблицу терминов. Если нашел, обрамлять слово тегом. Вариант плох тем, что не учитывается морфология. 2) Учет морфологии: К примеру, есть слово в документе "аллюминием". Для таких случаев думали модифицировать вариант из пункта 1 тем, что взять какую-то морфологическую библиотеку, найти для каждого слова именительный падеж (в данном случае "аллюминий"), и искать в таблице терминов по именительному падежу. Но тут есть проблема, что морфология может плохо работать для специальных терминов. Например, таких как "магальдрат". Я не знаю, как работают технологии морфологического разбора, но если они работают через словарь, то вряд-ли в словаре есть такие специальные термины. Поэтому если где-то будет в тексте слово "магальдратами", то не факт, что морфологией правильно будет найден именительный падеж. 3) Составные термины: Допустим даже, если нашли даже библиотеку морфологии. Всплывает следующая проблема. Как быть с составными терминами? Например, тот же "хлорид натрия". Если там еще и он используется в каком-то падеже. Например, в тексте встречается "хлоридом натрия". Тут, во-первых, в именительном падеже это будет "хлорид натрий", а в таблице терминов это "хлорид натрия". Уже не совпадает. А во-вторых, уже не получится в исходном документе делать цикл по одному слову, так как термины бывают многословные. 4) Обратный проход: Поэтому рисуется здесь обратное решение. Идти по всем 100 000 значениям таблицы терминов, и проверять вхождение каждого из них в документ. Это похоже на правильное решение. Но как быть тогда снова-таки с морфологией? Ведь в таблице терминов все в именительном падеже, а в документе в любом падеже. Я уверен, что задача решаема. Ведь гугл ищет же комбинации слов с учетом морфологии. Подозреваю, что Lucen'ом можно будет эту задачу также решить. Вопрос производительности здесь не критичный - возможна задержка в обработке документа хоть в несколько часов. Главное, чтобы тяжелая по ресурсам обработка не мешала жить основной части системы. Новые документы будут появляться примерно раз в час. Понятно, что для производительности лучше будет написать хранимую процедуру в БД, но можно ли морфологию использовать из хранимых процедур? Вопрос точности тоже не критичный. Допускается пропуск некоторых слов, которые могли бы быть ссылкой. 80% терминов ссылками - это отличный результат. Вобщем, подскажите, пожалуйста, как правильно разработать такое решение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.05.2012, 18:07:26 |
|
||
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
По сути, выходит у меня обратная задача от поисковой. По классике пользователь задает поисковый запрос, а система ищет список документов, который соответствует запросу. У меня же фактически обратная задача — по одному документу найти те поисковые запросы (термины, в том числе многословные), по которым этот документ может найтись, и найти место вхождения запроса в документ. А количество поисковых запросов (терминов) порядка 100 000. Вот и как сделать достаточно производительное решение? Как решить мою задачу с помощью Lucene/Solr (который у нас уже подключен) да и вообще? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2012, 15:03:41 |
|
||
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
А не понятно, что вы хотите. Пока лишь видно, что вам не нужен инвертированный индекс, а нужен обычный. Также не понятно. Вот есть у меня документ из слов A, B, C: d = {A, B, C}. Какие запросы вы хотите увидеть? Тут можно много придумать: A, B, C, A B, A C, B C ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.05.2012, 15:27:53 |
|
||
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
Leonidv, +1 Напишу первое, что приходит на ум, как решение этого. Как понял, в общем. Решить с Lucene можно, например, таким образом: написать свой Analyzer. Пример того, как его реализовать есть в Lucene in Action - синонимичный анализатор. В Tokenizer будете разбивать пришедший текст. Каким образом... ну, например, есть у вас мапа терминов/кусков терминов: натрия натрий хлорид хлор пришел текст: "натрия хлорид используется" Читаете первое слово - "натрия", смотрите, есть ли такой в мапе - есть, заносите в результирующий токен. Читаете второе слово - "хлорид", смотрите, есть ли такой в мапе - есть, заносите в результирующий токен. Читаете третье слово --------- нет, токен оформился. Следующее слово будет в следующем токене. Итак, первый токен = "натрия хлорид", второй - "используется" Получив разделение на токене, в TokenFilter можете творить, что угодно - обрамлять, например, как раз ссылкой куда-то на основе какой-то вашей собственной таблицы вроде: натрия хлорид --> id термина хлорид натрия --> id термина NaCl --> id термина Вот. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2012, 13:05:36 |
|
||
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
LeonidvА не понятно, что вы хотите. Пока лишь видно, что вам не нужен инвертированный индекс, а нужен обычный. Также не понятно. Вот есть у меня документ из слов A, B, C: d = {A, B, C}. Какие запросы вы хотите увидеть? Тут можно много придумать: A, B, C, A B, A C, B C Вопрос в следующем. Есть документ, нужно найти вхождение у него всех терминов. Пример. Есть документ на вход: Код: plaintext В таблице терминов есть следующие записи: Код: plaintext 1. 2. 3. 4. 5. Система должна проанализировать входной документ, и тегами обрамить вхождение терминов в документ. В нашем случае на выходе мы должны получить: Код: plaintext Как это сделать? P.S.: Здесь прошу обратить внимание на морфологию. В исходном справочнике терминов есть термин "хлорид натрия", а в документе этот термин в родительном падеже: "хлорид а натрия". Также прошу учесть, что если найти именительный падеж от "хлорида натрия" по каждому слову, то мы получим "хлорид натрий", что не совпадает со значением в словаре терминов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2012, 12:22:55 |
|
||
|
Есть в базе названия терминов. Как в тексте документа найти вхождения всех терминов?
|
|||
|---|---|---|---|
|
#18+
Vetal, Имхо. Ну тут же все равно 2 пути. Первый - это морфологический анализ. Обратите внимание на Морфологический анализатор под Lucene . Я его не смотрел, но возможно, или его, или его код можно использовать для морфологического анализа. Либо второй - синонимичный разбор: натрия хлорид --> id термина хлорид натрия --> id термина NaCl --> id термина ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2012, 14:22:46 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=37813354&tid=2131704]: |
0ms |
get settings: |
17ms |
get forum list: |
26ms |
check forum access: |
7ms |
check topic access: |
7ms |
track hit: |
51ms |
get topic data: |
20ms |
get forum data: |
5ms |
get page messages: |
72ms |
get tp. blocked users: |
2ms |
| others: | 370ms |
| total: | 577ms |

| 0 / 0 |
