在lucene中搜索

时间:2014-12-10 10:58:38

标签: java lucene full-text-search

我正在尝试在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来获得预期的结果,因为我的代码没有给我预期的结果。 提前谢谢。

2 个答案:

答案 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);