Синонимы использованием 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% Лучший способ сделать это...но в прошлом это отлично работало на меня.