提问者:小点点

高效地返回Lucene中所有查询命中的字段


我有一个相当大的 lucene 索引,查询可以达到大约 5000 个文档左右。我将我的应用程序元数据存储在 lucene 的一个字段中(除了文本内容),并且需要快速访问所有 5000 次点击的这个小元数据字段。目前,我的代码看起来像这样:

MapFieldSelector field = new MapFieldSelector("metaData");
ScoreDoc[] hits = searcher.search(query, null, 10000).scoreDocs;
for (int i = 0; i < hits.length; i++) {
    int index_doc_id = hits[i].doc;
    Document hitDoc = searcher.doc(index_doc_id, field); // expensive esp with disk-based lucene index
    metadata = hitDoc.getFieldable("metaData").stringValue();
}

然而,这非常慢,因为每次调用searcher.doc()都非常昂贵。有没有一种方法可以“批量”提取所有可能响应更快的命中的字段?或者其他什么方法能让这个工作更快?(ScoreDoc中唯一的东西似乎是Lucene文档id,我认为不应该依赖它。否则我会维护一个Lucene文档id -

更新:我现在尝试使用FieldCache,如下所示:

String metadatas[] = org.apache.lucene.search.FieldCache.DEFAULT.getStrings(searcher.getIndexReader(), "metaData");

当我打开索引并在查询时:

int ldocId = hits[i].doc;
String metadata = metadatas[ldocId]; 

这对我很有效。


共1个答案

匿名用户

提高性能的最佳选择是尽可能减少存储的数据。如果您在索引中存储了大量内容字段,则将其设置为仅索引而不是存储会提高性能。将内容存储在Lucene外部,以便在索引中找到命中后获取,通常是一个更好的主意。

也有可能存在一个更好的方法来达到你想要的最终结果。我猜5000组元数据不是这里的最终结果。在Lucene中,对索引数据的分析可能更容易处理,而不是首先从索引中取出所有数据。根据你提供的信息,我不知道这在你的情况下是否可行,但肯定值得一看。