Синонимы использованием Lucene
каков наилучший способ обработки синонимов (фраз) с помощью Lucene? Особенно, когда мне нужно выполнить такие запросы, как: a или b или c не d
Как насчет добавления нового поля под названием "синонимы" к каждому документу при индексировании? Значение этого поля будет содержать список всех синонимов. Он будет добавлен в документ только тогда, когда этот документ любым из указанных синонимов.
затем я выполню поисковый запрос" или", который будет искать ключевое слово поиска в этом поле вместе с другие месторождения.
может ли этот подход хорошо работать для любого запроса?
к вашему сведению, Синонимы в моем приложении полностью пользовательские, а не из английского словаря...т. е. "Мировой лидер в финансах "может также означать" Лучший инвестиционный банк "или" финансовая компания Fortune 500 " и т. д.
пожалуйста, предложите.
спасибо.
3 ответов
существует вклад в проект Lucene под названием "wordnet". Согласно документация:
этот пакет использует синонимы, определенные WordNet для создания индекса Lucene, хранящего их, который, в свою очередь, может использоваться для расширения запроса. Обычно вы запускаете Syns2Index один раз для создания индекса запроса/"база данных", а затем вызываете SynExpand.расширять.(..) для расширения запроса.
Она включает в себя образец того, что он делает:
Если вы передадите запрос "big dog", то он распечатает:
запрос:
big adult^0.9 bad^0.9 bighearted^0.9 boastful^0.9 boastfully^0.9 bounteous^0.9 bountiful^0.9 braggy^0.9 crowing^0.9 freehanded^0.9 giving^0.9 grown^0.9 grownup^0.9 handsome^0.9 large^0.9 liberal^0.9 magnanimous^0.9 momentous^0.9 openhanded^0.9 prominent^0.9 swelled^0.9 vainglorious^0.9 vauntingly^0.9 dog andiron^0.9 blackguard^0.9 bounder^0.9 cad^0.9 chase^0.9 click^0.9 detent^0.9 dogtooth^0.9 firedog^0.9 frank^0.9 frankfurter^0.9 frump^0.9 heel^0.9 hotdog^0.9 hound^0.9 pawl^0.9 tag^0.9 tail^0.9 track^0.9 trail^0.9 weenie^0.9 wiener^0.9 wienerwurst^0.9
он поставляется в комплекте со стандартным распределением Lucene в каталоге "contrib".
вы можете получить объект запроса после анализа входной строки запроса с помощью QueryParser.разбор.)(
в большинстве случаев запрос верхнего уровня является логическим запросом с подзапросами в качестве его дочерних. Вы можете рекурсивно перебирать объект query. Когда вы нажимаете объект TermQuery или PhraseQuery, вы можете получить (sub)запрос и заменить этот объект запроса на объект boolean query, состоящий из его синонимов, если таковые имеются.
по существу, вы трансформируете свой оригинал запрос
a OR b AND c
to
(a OR synA) OR (b OR synB1 OR synB2) AND c
работа с объектом запроса гарантирует, что вы просто замените листовые узлы запроса новыми запросами и не будете возиться с произвольно сложной иерархией запросов.
Я предпочитаю запускать поиск, используя всю введенную фразу, и весить все, что возвращается тяжелее, чем следующая серия поисков. Затем мне нравится перебирать каждое слово во фразе и искать с этим, когда эти результаты получают более низкий балл. Затем я агрегирую оценки для всех элементов, возвращенных более одного раза, и сортирую результаты соответственно. Это может быть не 100% Лучший способ сделать это...но в прошлом это отлично работало на меня.