Note that another benefit of option 2 is that we can down the road (post 3.4) 
implement a way to pre-select which facet element is enabled (say you want to 
filter by Epson and Canon by default for the first query).

facet().name("Brand")
  .onField("brand")
  .discrete()
  .select("Epson", "Canon")
  .createFacetRequest();

Same for range, which might be even more useful.

BTW what's the facet.value() for a range facet?

On 14 mars 2011, at 15:29, Emmanuel Bernard wrote:

> As you guys know I've not been comfortable with the idea of reusing Filter as 
> an implementation as it seem to be it is an implementation detail that we 
> might change down the road and that is of no interest to the user.
> 
> Instead of bitching abstractly, I've decided to implement a CDI style bean 
> that implement faceted search to see how the API us used.
> 
> Note that I have tried to implement what amazon does 
> http://www.amazon.com/gp/search/ref=sr_nr_scat_392442011_ln?rh=n%3A392442011%2Ck%3Ascreen&keywords=screen&ie=UTF8&qid=1300105439&scn=392442011&h=9aa8a737035ed82d321ca117e8f48611956411e5#/ref=nb_sb_noss?url=node%3D392442011&field-keywords=screen&rh=n%3A172282%2Cn%3A%21493964%2Cn%3A281407%2Cn%3A172575%2Cn%3A392442011%2Ck%3Ascreen
> 
> My feature list was:
> - multiple facets per query
> - ability to select one or more discrete facet values on a given facet (ie 
> brand = epson or canon)
> - ability to display the facet menu on the left
> - ability to remember the state of the selected facet values
> 
> While implementing it I've found several proposals for enhancement:
> - should we rename in thw facet DSL createFacet to createFacetRequest(), as 
> it's the object returned
> - does facet work with pagination (ie is not affected) => we did some 
> optimization around QueryHits when paginating => add a unit test
> - jpa.FullTextQuery does not have the facet methods
> - move Facet methods hosted on FTQuery to a FacetManager interface and do 
> ftQuery.getFacetManager().enableFacet("cdscds");
> - make FacetRequest / FacetResults interfaces?
> - Facet should implement equals / hashCode or else we cannot remember the 
> facet selected
> - //TODO should the index be included in object Facet? Not sure but worth 
> thinking about => probably not if Facet objects change indexes from one query 
> to the other
> - should we rename Facet to FacetElement? We seem to talk about Facets as the 
> global concept whereas Facet the object represent one of the results of the 
> Facet.
> 
> The client of the service is as followed
> https://gist.github.com/869181
> 
> The solution with the current API is as followed
> https://gist.github.com/869143
> 
> In this implementation:
> - I need to keep some kind of state besides the query to remember which facet 
> has been selected by the user and which one have not been.
> - I need to remember this state across query re execution: even if the 
> request (and thus the facetREsults) are updated, I need to remember this 
> state or the user will yell
> - FacetFilter as it is does not solve the problem at had as I need to:
>  . use a OR filter for selected elements across a Facet
>  . use AndFilter to aggregate the various facets and filter the results 
> across all of them
> - I ended up writing and manipulating various OrFacetFilter and AndFilter 
> object which are not exactly easy to play with
> 
> I've worked on an alternative API that internalize the management of this 
> facet element selection so that the whole filter tree can be managed by 
> Hibernate Search itself and exposed to the user as a service
> 
> https://gist.github.com/869145
> 
> Query execution and faceting display are of similar complexity. But the 
> select or deselect method is simpler. Also note that I no longer need to 
> implement or manipulate And/Or filters myself (and potentially forget to set 
> it).
> I have attached the state of the selected facet elements on the FacetRequest 
> (the FacetResults are destroyed and reset upon requery). We might want to 
> move it up to FacetManager (not shown here), I ahve not thought about it.
> 
> What do you guys think? If I had to write a book on Hibernate Search, I'd 
> prefer the second option by a big margin.
> 
> On 11 mars 2011, at 20:08, Hardy Ferentschik wrote:
> 
>> Hi,
>> 
>> sorry for the following lengthy code example, but it is hard to  
>> demonstrate this much shorter.
>> The example shows how you can enable multiple facets and then continuously  
>> restrict the query result
>> by chaining facets into a FacetFilter (which delegates to a ChainedFilter  
>> underneath). WDYT?
>> If you want to see all the code or even get the feature branch -  
>> https://github.com/hferentschik/hibernate-search/blob/HSEARCH-706
>> 
>> 
>>      public void testMultipleFacetDrillDown() throws Exception {
>>              final String ccsFacetName = "ccs";
>>              final String ccsFacetFieldName = "cubicCapacity";
>>              FacetRequest ccsFacetRequest = queryBuilder( Car.class ).facet()
>>                              .name( ccsFacetName )
>>                              .onField( ccsFacetFieldName )
>>                              .discrete()
>>                              .createFacet();
>> 
>>              final String colorFacetName = "color";
>>              final String colorFacetFieldName = "color";
>>              FacetRequest colorFacetRequest = queryBuilder( Car.class 
>> ).facet()
>>                              .name( colorFacetName )
>>                              .onField( colorFacetFieldName )
>>                              .discrete()
>>                              .createFacet();
>> 
>>              FullTextQuery query = createMatchAllQuery( Car.class );
>>              query.enableFacet( colorFacetRequest );
>>              query.enableFacet( ccsFacetRequest );
>>              assertEquals( "Wrong number of query matches", 50, 
>> query.getResultSize()  
>> );
>> 
>>              List<Facet> colorFacetList = getFacetListForFacet( query, 
>> colorFacetName  
>> );
>>              assertFacetCounts( colorFacetList, new int[] { 12, 12, 12, 12, 
>> 2 } );
>> 
>>              List<Facet> ccsFacetList = getFacetListForFacet( query, 
>> ccsFacetName );
>>              assertFacetCounts( ccsFacetList, new int[] { 17, 16, 16, 1 } );
>> 
>>              FacetFilter facetFilter = new FacetFilter();
>>              query.setFilter( facetFilter );
>> 
>>              facetFilter.addFacet( colorFacetList.get( 0 ) );
>>              colorFacetList = getFacetListForFacet( query, colorFacetName );
>>              assertFacetCounts( colorFacetList, new int[] { 12, 0, 0, 0, 0 } 
>> );
>> 
>>              ccsFacetList = getFacetListForFacet( query, ccsFacetName );
>>              assertFacetCounts( ccsFacetList, new int[] { 4, 4, 4, 0 } );
>> 
>>              facetFilter.addFacet( ccsFacetList.get( 0 ) );
>>              // needs to set the filter explicitly atm, because I need the 
>> query  
>> state to reset
>>              query.setFilter( facetFilter );
>>              colorFacetList = getFacetListForFacet( query, colorFacetName );
>>              assertFacetCounts( colorFacetList, new int[] { 4, 0, 0, 0, 0 } 
>> );
>> 
>>              ccsFacetList = getFacetListForFacet( query, ccsFacetName );
>>              assertFacetCounts( ccsFacetList, new int[] { 4, 0, 0, 0 } );
>>      }
>> 
>> I like the idea of using Lucene Filters to implement the drilldown for. It  
>> seems the most natural and the original query stays
>> untouched.
>> 
>> --Hardy
>> 
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev@lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
> 
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev


_______________________________________________
hibernate-dev mailing list
hibernate-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to