Какой самый эффективный способ получить все соответствующие документы из запроса в Lucene, не отсортированный? - PullRequest
6 голосов
/ 25 марта 2011

Я ищу запрос на поддержание внутренней целостности;например, удаление всех следов определенного поля / значения из индекса.Поэтому важно, чтобы я нашел все совпадающие документы (не только верхние n документов), но порядок, в котором они возвращаются, не имеет значения.

В соответствии с документами, похоже, мне нужноиспользовать метод Searcher.Search( Query, Collector ), но нет встроенного класса Collector, который делает то, что мне нужно.

Должен ли я получить свой собственный Collector для этой цели?Что мне нужно иметь в виду при этом?

Ответы [ 2 ]

4 голосов
/ 25 марта 2011

Оказывается, это было намного проще, чем я ожидал. Я просто использовал пример реализации на http://lucene.apache.org/java/2_9_0/api/core/org/apache/lucene/search/Collector.html и записал номера документов, переданные методу Collect(), в List, выставив его как открытое свойство Docs.

Затем я просто повторяю это свойство, передавая число обратно Searcher, чтобы получить правильное Document:

var searcher = new IndexSearcher( reader );
var collector = new IntegralCollector(); // my custom Collector
searcher.Search( query, collector );
var result = new Document[ collector.Docs.Count ];
for ( int i = 0; i < collector.Docs.Count; i++ )
    result[ i ] = searcher.Doc( collector.Docs[ i ] );
searcher.Close(); // this is probably not needed
reader.Close();

Пока что в предварительных тестах все работает нормально.

Обновление: Вот код для IntegralCollector:

internal class IntegralCollector: Lucene.Net.Search.Collector {
    private int _docBase;

    private List<int> _docs = new List<int>();
    public List<int> Docs {
        get { return _docs; }
    }

    public override bool AcceptsDocsOutOfOrder() {
        return true;
    }

    public override void Collect( int doc ) {
        _docs.Add( _docBase + doc );
    }

    public override void SetNextReader( Lucene.Net.Index.IndexReader reader, int docBase ) {
        _docBase = docBase;
    }

    public override void SetScorer( Lucene.Net.Search.Scorer scorer ) {
    }
}
0 голосов
/ 26 марта 2011

Нет необходимости писать сборщик обращений, если вы просто хотите получить все объекты Document в индексе. Просто выполните цикл от 0 до maxDoc () и вызовите reader.document () для каждого идентификатора документа, пропуская уже удаленные документы:

for (int i=0; i<reader.maxDoc(); i++) {
   if (reader.isDeleted(i))
      continue;
   results[i] = reader.document(i);
}
...