Reputation: 121
I am working with lucene 5.2.1 and I am trying to filter the results of a query. I don't want to add Occur.SHOULD clauses because I don't want filters to influence the rank of retrieved documents (I need filters only to remove improper documents). Nevertheless I want to order the query results using my own Sort rule. Until now I have this piece of code:
BooleanQuery bq = ... //user's query + filters
maxdocs = 50;
SortField[] fields = {SortField.FIELD_SCORE, new SortField("stars", SortField.Type.DOUBLE, true)};
Sort sort = new Sort(fields);
TopDocs docs = mySearcher.search(bq, maxdocs, sort);
where bq is a BooleanQuery containing both the actual user's query (Occur.MUST and Occur.SHOULD clauses) and the filters (Occur.FILTER clauses). For example, I added to bq the filter on "category" field as follows:
if (category.length() > 0) {
categoryParser = new QueryParser("categories", businessAnalyzer);
categoryParser.setAllowLeadingWildcard(true);
categoryParser.setLowercaseExpandedTerms(true);
categoryParser.setAutoGeneratePhraseQueries(true);
categoryQuery = categoryParser.parse("*" + category + "*");
bq.add(categoryQuery, Occur.FILTER);
}
Filters are not actually working very vell (I always get 0 results) so I must be missing something. I also tried a different approach using Filter, QueryWrapperFilter and FilteredQuery, but it still returns 0 results:
//filters contains the previous bq.add(category_filter, Occur.FILTER);
Filter filter = new QueryWrapperFilter(filters);
FilteredQuery filtered_query = new FilteredQuery(bq, filter);
I have read the documentation, and I guess that my problem is that I want to both apply filters and sort at the same time. But a lot of stuff in the class Filter is deprecated, so I really need an input to move forward. Anybody knows?
Upvotes: 1
Views: 756
Reputation: 121
I solved the problem! I both used the finalQuery, suggested by @user1071777, and checked out the categoryQuery, as suggested by @femtoRgon. The categoryQuery was giving me problems because I parsed it adding wildcards to the input string, as follows:
categoryParser = new QueryParser("categories", myAnalyzer);
categoryParser.setAllowLeadingWildcard(true);
categoryParser.setLowercaseExpandedTerms(true);
categoryParser.setAutoGeneratePhraseQueries(true);
//NOT WORKING: categoryQuery = categoryParser.parse("*" + category + "*");
categoryQuery = categoryParser.parse(category);
filters.add(categoryQuery, Occur.SHOULD);
It seems that adding those wildcards is not allowed. You can find my updated versione of the code above, it works!
BooleanQuery finalQuery = new BooleanQuery();
Query filters = ... //add filter clauses to filter query
finalQuery.add(bq, Occur.MUST); //bq is still the user's boolean query
finalQuery.add(filters, Occur.FILTER);
Thank you all!
Upvotes: 0
Reputation: 1307
You can achieve this by using multiple boolean queries. I assume the results "must" match the filters.
// Your user query, which contains both Occur.SHOULD and Occur.MUST clauses
BooleanQuery userQuery = createUserQuery();
// Your filter query, could be a BooleanQuery on its own
Query filterQuery = getFilterQuery();
BooleanQuery finalQuery = new BooleanQuery();
finalQuery.add(userQuery, Occur.MUST);
finalQuery.add(filterQuery, Occur.FILTER);
// Search using the finalQuery
TopDocs docs = mySearcher.search(finalQuery, maxdocs, sort);
Upvotes: 1