我正在尝试在lucene中搜索我的资源。
Query q1 = new MultiFieldQueryParser(new String[] { "products",
"name"}, analyzer).parse(queryStr1);
Query q2 = new TermQuery(new Term("keywords", queryStr2));
IndexReader ir = DirectoryReader.open(indexLocation);
IndexSearcher is = new IndexSearcher(ir);
TopScoreDocCollector collector = TopScoreDocCollector.create(
reqHits, true);
is.search(q1, collector);
ScoreDoc results[] = collector.topDocs().scoreDocs;
TopDocs topDocs = null;
for (ScoreDoc scoreDoc : results) {
topDocs = is.searchAfter(scoreDoc, q2, 1);
}
ScoreDoc deepResults[] = topDocs.scoreDocs;
for (int i = 0; i < deepResults.length; i++) {
Document doc = is.doc(deepResults[i].doc);
System.out.println(doc.get("name"));
}
searchAfter()可以应用于之前搜索的scoreDocs。但是它需要scoreDoc作为第一个参数,所以我循环以实现单个scoreDoc。我不知道我们如何应用afterSearch来获得预期的结果,因为我的代码没有给我预期的结果。 提前谢谢。
答案 0 :(得分:1)
这是searchAfter
的错误用法。我们的想法是使用结果大小的上限进行一次搜索,然后使用searchAfter
重复搜索,从前一个结果传递 last scoreDoc,这样您就可以得到下一个结果页”。这就是Lucene支持无界结果集大小的方法。
答案 1 :(得分:0)
有两种方法可以在q2
的结果中搜索q1
的结果。
最简单的方法是将两个查询与布尔查询结合起来:
BooleanQuery finalQuery = new BooleanQuery();
finalQuery.add(q1, BooleanClause.Occur.MUST);
finalQuery.add(q2, BooleanClause.Occur.MUST);
is.search(finalQuery, collector);
即使您的用例是从q1
获取并显示结果,然后将q2
作为用户的输入,然后运行其他搜索,保留q1
,并生成BooleanQuery
因为最终查询仍然是一个很好的方法。
您还可以使用Filter
进行其中一个查询。如果其中一个(例如q1
)是您希望经常重复使用的查询,并且可以从缓存结果中受益,则此功能特别有用,例如:
Filter q1Filter = new CachingWrapperFilter(new QueryWrapperFilter(q1));
is.search(q2, q1Filter, collector);