从Lucene的查询中检索所有匹配文档的最有效方法是什么?

时间:2011-03-25 15:58:37

标签: c# .net lucene lucene.net

我希望为维护内部完整性而执行查询;例如,从索引中删除特定字段/值的所有跟踪。因此,找到所有匹配文档(不仅仅是前n个文档)非常重要,但返回的顺序无关紧要。

根据文档,看起来我需要使用Searcher.Search( Query, Collector )方法,但是没有内置的Collector类可以满足我的需要。

我应该为此目的派生自己的收藏家吗?这样做时我需要记住什么?

2 个答案:

答案 0 :(得分:4)

事实证明这比我预期的要容易得多。我刚刚在http://lucene.apache.org/java/2_9_0/api/core/org/apache/lucene/search/Collector.html使用了示例实现,并记录了传递给List中Collect()方法的文档编号,并将其公开为公共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 ) {
    }
}

答案 1 :(得分:0)

如果您只想获取索引中的所有Document对象,则无需编写命中收集器。只需从0循环到maxDoc()并在每个文档ID上调用reader.document(),确保跳过已删除的文档:

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