Lucene 3 перебирает все хиты - PullRequest
2 голосов
/ 21 июля 2010

Я в процессе обновления инструмента, использующего индекс Lucene.В рамках этого обновления мы переходим с Lucene 2.0.0 на 3.0.2.По большей части это было совершенно просто.Тем не менее, в одном случае я не могу найти простое преобразование.

По сути, у меня есть простой запрос, и мне нужно перебрать все попадания.В Lucene 2 это было просто, например:

Hits hits = indexSearcher.search(query);
for(int i=0 ; i<hits.length() ; i++){
  // Process hit
}

В Lucene 3 API для IndexSearcher значительно изменился, и хотя я могу собрать воедино что-то, что работает, это только путем получения вершины Xдокументы и убедившись, что X достаточно большой.

Хотя число попаданий (в моем случае) обычно составляет от нуля до десяти, существует аномальная ситуация, когда их число может быть намного выше.Наличие фиксированного лимита для этого кажется неправильным.Кроме того, установка действительно высокого предела приводит к OOME, что означает, что пространство для всех X возможных попаданий выделяется немедленно.Поскольку эта операция выполняется много , желательно что-то достаточно эффективное.

Редактировать:

В настоящее время у меня работает следующее:

TopDocs hits = indexSearcher.search(query, MAX_HITS);
for (int i=0 ; i<hits.totalHits ; i++) {
   // Process hit
}

Это прекрасно работает, за исключением того, что

a) что, если будет больше совпадений, чем MAX_HITS?

и

b) , если MAX_HITS велик, то я трачу впустую память, так как место для каждого удара выделяется до того, как поиск будет выполнен.

Поскольку большую часть времени будет только несколькохиты, я не против делать последующие поиски, чтобы получить последующие хиты, но я не могу найти способ сделать это.

Ответы [ 4 ]

2 голосов
/ 09 февраля 2012

@ Крис - Я тоже столкнулся с этой проблемой, это помогло мне.Попробуйте это:

TopDocs tp = ms.search(query, 1); 

TopDocs hits = indexSearcher.search(query, tp.totalHits);
for (int i=0 ; i<hits.totalHits ; i++) {
   // Process hit
}

Согласно Uwe в ссылке ниже tp.totalHits ".. будет по-прежнему считать все попадания, но вернет только 1."

См. Подробности в ссылке из Java-пользовательские почтовые архивы Lucene Apache - http://www.gossamer -threads.com / lists / lucene / java-user / 95032

2 голосов
/ 22 июля 2010

IndexSearcher имеет метод docFreq(Term).Вызов его не приводит к снижению производительности, и его вывод является подходящим входным параметром для количества документов, которые нужно получить.

Например,

int freq = searcher.docFreq(new Term(FIELD, value));
TopDocs hits = indexSearcher.search(query, freq);
for (int i=0 ; i<hits.totalHits ; i++) {
   // Process hit
}

Это работает, потому что мой запрос по сутиTermQuery.Если бы это был более сложный запрос, он бы не подходил.

0 голосов
/ 21 июля 2010

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

Не упустите крайний случай отсутствия документов в индексе, хотя ...

Надеюсь, это поможет,

0 голосов
/ 21 июля 2010

Почему вы не используете Searcher.search (Query query, int n)? Вы можете указать количество результатов, которые вы хотите вернуть, и вы можете использовать объект TopDocs, который возвращается, чтобы перебрать результаты.

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

TopDocs содержит только идентификаторы и оценки, поэтому у вас не должно быть проблем с памятью даже при большом n.

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