[hibernate-dev] Named Lucene Filters

Emmanuel Bernard emmanuel at hibernate.org
Tue Jul 24 23:00:13 EDT 2007


I've just committed support for Lucene Filters inside Hibernate Search

I like the global idea but not entirely happy yet with some of the  
details. I would appreciate some feedbacks on it, especially how to  
simplify the user experience. Lucene Filters are very similar to  
Hibernate Core filters in the way they interact with data.

How to define filters

@FullTextFilterDef(name = "bestDriver", impl =  
BestDriversFilter.class) //on any of the @Indexed class, there is no  
association to the class

BestDriverFilter is a org.apache.lucene.search.Filter implementation

public class BestDriversFilter extends Filter {
	public BitSet bits(IndexReader reader) throws IOException {
		BitSet bitSet = new BitSet( reader.maxDoc() );
		TermDocs termDocs = reader.termDocs( new Term("score", "5") );
		while ( termDocs.next() ) {
			bitSet.set( termDocs.doc() );
		}
		return bitSet;
	}
}

To enable it on a given fullTextQuery:
fullTextQuery.enableFullTextFilter( "bestDriver");
the query results are now filtered

Sometimes (often), the filter needs to get some parameters injected.  
The filter creation might be fairly complex and require a factory.  
The following example shows how it works in complex cases:

@FullTextFilterDef(name = "security", impl =  
SecurityFilterFactory.class) //on any @Indexed class, there is no  
association to the class

/**
  * this is the way most Query filters will likely to be implemented
  */
public class SecurityFilterFactory {
	private String login;

	/**
	 * injected parameter
	 */
	public void setLogin(String login) {
		this.login = login;
	}

	@Key
	public FilterKey getKey() {
		StandardFilterKey key = new StandardFilterKey();
		key.addParameter( login );
		return key;
	}

	@Factory
	public Filter getFilter() {
		Query query = new TermQuery( new Term("teacher", login) );
		return new CachingWrapperFilter( new QueryWrapperFilter(query) );
	}
}

setLogin is the way parameters are injected (see below)

the method marked as @Key must return a FilterKey. This object must  
implement equals and hashCode in a way that uniquely identify a given  
filter type with a given set of parameters (for caching, see later).  
StandardFilterKey is a standard implementation to make things simpler  
in common cases. @Key is necessary when parameters are used. @Key can  
be define on a factory method or on a filter method.
PS Key is the part I'm not too keen about. But to enable caching

the method marked as @Factory is used to return a Filter instance  
(with the appropriate parameters set).

To enable this filter:
To enable it on a given fullTextQuery:
fullTextQuery.enableFullTextFilter( "bestDriver").setParameter 
("login", "emmanuel");
the query results are now filtered
the parameter key is the setter name, the parameter value is any object.

More than one filter can be applied on a given query, the filtered  
intersection is applied.

Filter instances are cached (per their key). It is useful when used  
in conjunction with a Lucene CachingWrapperFilter: that way filters  
computation is only done the first time.

The default caching strategy is a MRU + soft reference ( thanks  
Steve ;) ), but it can be overridden by a custom implementation.

I am contemplating the idea of adding a @FullTextFilterDef.cache  
parameter to enable/disable the cache on a per filter definition  
basis. It would also help to get rid of @Key (at the cost of not  
caching).

If the user wants to deal with the filters manually (for whatever  
reason) there is a fullTextSession.setFilter(securityfilter);
I'm not sure I want to keep this method alive though.

The code has just been committed, please review (esp the method /  
class naming) and let me know what you think, and how it could be  
made simpler. The test case are in org.hibernate.search.test.filter

Emmanuel

PS I've attached the patch if you prefer reading it rather than TRUNK

-------------- next part --------------
A non-text attachment was scrubbed...
Name: filter.diff
Type: application/octet-stream
Size: 48586 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/hibernate-dev/attachments/20070724/bbbda439/attachment.obj 


More information about the hibernate-dev mailing list