Как получить верхние термины для подмножества документов в индексе Lucene? - PullRequest
6 голосов
/ 12 октября 2008

Я знаю, что можно получить верхние термины в индексе Lucene, но есть ли способ получить верхние термины на основе подмножества индекса Lucene?

т.е. Каковы главные термины в индексе для документов в определенном диапазоне дат?

Ответы [ 2 ]

5 голосов
/ 22 октября 2008

В идеале была бы где-то утилита для этого, но я не знаю ни одной. Тем не менее, это не слишком сложно сделать это «вручную» достаточно эффективным способом. Я предполагаю, что у вас уже есть объект Query и / или Filter, который вы можете использовать для определения подмножества интереса.

Сначала создайте в памяти список всех идентификаторов документов в вашем подмножестве индекса. Вы можете использовать IndexSearcher.search(Query, Filter, HitCollector), чтобы сделать это очень быстро; HitCollector документация содержит пример, который, похоже, должен работать, или вы можете использовать другой контейнер для хранения идентификаторов ваших документов.

Затем инициализируйте пустой HashMap (или любой другой), чтобы сопоставить термины с общей частотой, и заполните карту, вызвав один из методов IndexReader.getTermFreqVector для каждого документа и интересующей области. Форма с тремя аргументами кажется более простой, но любой из них должен быть в порядке. Для формы с тремя аргументами вы должны сделать TermVectorMapper, чей метод map проверяет, присутствует ли term на карте, ассоциирует ли его с frequency, если нет, или добавляет frequency к существующему значению, если так , Обязательно используйте один и тот же объект TermVectorMapper во всех вызовах getTermFreqVector на этом этапе, а не создавайте новый для каждого документа в цикле. Вы также можете немного ускорить процесс, переопределив isIgnoringPositions() и isIgnoringOffsets(); ваш объект должен вернуть true для обоих. Похоже, ваш TermVectorMapper также может быть вынужден определить метод setExpectations, но ничего не нужно делать.

Как только вы построите свою карту, просто сортируйте элементы карты по убыванию частоты и считывайте сколько угодно топ терминов. Если вы заранее знаете, сколько терминов вы хотите получить, вы можете предпочесть какой-нибудь причудливый алгоритм на основе кучи, чтобы найти лучшие k элементов за линейное время вместо использования O ( n *). 1029 * log n ) сортировка. Я полагаю, что старый вид будет довольно быстрым на практике. Но это зависит от вас.

Если вы предпочитаете, вы можете объединить первые два этапа, напрямую вызвав HitCollector getTermFreqVector. Это, безусловно, должно давать одинаково правильные результаты, и интуитивно кажется, что это будет проще и лучше, но документы, кажется, предупреждают, что это, вероятно, будет немного медленнее, чем двухпроходный подход (на той же странице, что и пример HitCollector выше). Или я могу неправильно истолковать их предупреждение. Если вы чувствуете себя честолюбивым, вы можете попробовать это обоими способами, сравнить и сообщить нам.

0 голосов
/ 26 октября 2011

Подсчет TermVectors будет работать, но будет медленным, если есть много документов для повторения. Также обратите внимание, что если вы подразумеваете docFreq в верхних терминах, то не используйте счетчик в TermFreqVector, просто считайте термины как двоичные.

В качестве альтернативы, вы можете использовать такие термины, как количество фасетов. Используйте кэшированный фильтр для каждого термина; их BitSets могут использоваться для быстрого подсчета пересечений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...