The last few versions of lucene have deprecated several of the
interfaces we were using and this is necessitating a fairly major
upgrade of our code (which hasn't had much done to it for several
years).  I'm not complaining; the changes are probably necessary.

 

In reading LIA2, I've learned about filters and realized that several of
the things we do with queries should probably be done with filters
(queries where the boost was set to 0.0 was the clue).  But I'm having
trouble making them work.

 

Currently, the code that builds the user's query calls several other
classes and "asks" if they want to add something to the query.  These
classes return a BooleanClause if they do, null if they don't.  The main
query code will add the BooleanClause to a BooleanQuery object (ignoring
null returns).  The BooleanQuery object gets passed to the
Searcher.search() method.  This works fine

 

So, I did a similar thing for filters.  That is, I created a routine
that called the classes and asks if they have a FilterClause they want
to contribute.  If I get one back, then I add it to a BooleanFilter
object.  The BooleanFilter gets passed to the Searcher.search() method
(unless no one contributes a BooleanFilter object; then the filter
passed is null).

 

The first class I tried to migrate from providing a query to providing a
filter was the class that defined the categories of information the user
was interested in (it's called "sources" in the code).  Unfortunately,
it doesn't work.  Here's a snippet from the class:

 

    public BooleanClause getQuery()

    {

        if (!_doQuery) return null;

        

        ArrayList<String> sources = _optimizedSources;

        

        BooleanQuery bquery = new BooleanQuery(); 

        for (int i = 0 ; i < sources.size() ; i++)

        {

            TermQuery tq = new TermQuery(

                new Term( LuceneField.SOURCES, 

                        sources.get(i).toLowerCase()));

            bquery.add(tq, BooleanClause.Occur.SHOULD);

        }

        bquery.setBoost(0.0f);

        

        return new BooleanClause(bquery, BooleanClause.Occur.MUST);

    }

 

    public FilterClause getFilter()

    {

        if (_doQuery) return null;

        

        ArrayList<String> sources = _optimizedSources;

        

        TermsFilter termFilter = new TermsFilter(); 

        for (int i = 0 ; i < sources.size() ; i++)

        {

            Term t = new Term(LuceneField.SOURCES, 

                        sources.get(i).toLowerCase());

            termFilter.addTerm(t);

        }

 

        return new FilterClause(termFilter, BooleanClause.Occur.MUST);

    }

 

The _doQuery simply defines whether the sources are added to the query
or to the filter object(I added this simply for debugging).  If _doQuery
is true, then everything works fine.  If it is false (meaning the
getFilters() routine return a FilterClause), then the unit tests fail
(no hits are returned).  The test case has a single source and in the
case where the filter is invoked, this FilterClause will be the only
thing added to the BooleanFilter.

 

I've been staring at this code for two days and don't see what the issue
is.  Based on my understanding, I thought these would provide the same
result.  I'm probably missing something obvious or I don't understand
filters as well as I think I do.

 

Can anyone suggest what the problem is?

 

 

 

 

 

Reply via email to