mazerone
mazerone

Reputation: 121

Filtering problems in Lucene 5.2.1

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

Answers (2)

mazerone
mazerone

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

user1071777
user1071777

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

Related Questions