Reputation: 93
I am trying out a deep search in lucene for my resources.
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() can be applied on scoreDocs of a previous search.But it requires scoreDoc as the first parameter, so I loop inorder to achieve the individual scoreDoc. I am not sure how we can apply the afterSearch to get the results as expected since my code doesnt give me expected results. Thanks in advance.
Upvotes: 0
Views: 623
Reputation: 33341
There are a couple of ways to search for results of q2
within the results of q1
.
The simplest, is just combine the two queries with a boolean query:
BooleanQuery finalQuery = new BooleanQuery();
finalQuery.add(q1, BooleanClause.Occur.MUST);
finalQuery.add(q2, BooleanClause.Occur.MUST);
is.search(finalQuery, collector);
Even if your use case is to get and display results from q1
, and then take q2
as input from the user, and run another search, keeping q1
, and generating a BooleanQuery
as the the final query remains a good approach.
You could also use a Filter
for one of the queries. This is particularly useful if one of them, say q1
, is a query you expect to reuse frequently, and would benefit from caching the results of it, such as:
Filter q1Filter = new CachingWrapperFilter(new QueryWrapperFilter(q1));
is.search(q2, q1Filter, collector);
Upvotes: 0
Reputation: 200158
This is wrong usage of searchAfter
. The idea is to make one search with an upper bound on the result size, then repeat the search with searchAfter
, passing the last scoreDoc from the previous result, so you get the next "result page". This is how Lucene supports unbounded result set sizes.
Upvotes: 1