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