В идеале была бы где-то утилита для этого, но я не знаю ни одной. Тем не менее, это не слишком сложно сделать это «вручную» достаточно эффективным способом. Я предполагаю, что у вас уже есть объект 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 выше). Или я могу неправильно истолковать их предупреждение. Если вы чувствуете себя честолюбивым, вы можете попробовать это обоими способами, сравнить и сообщить нам.