-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: [HSEARCH-770] Range facets on numeric (null) fields issue
PostPosted: Wed May 18, 2011 2:55 pm 
Beginner
Beginner

Joined: Mon Apr 11, 2011 7:56 am
Posts: 38
(edit: changed topic title to better reflect content ;))
I'm having troubles with getting facets from the facet manager. The weird thing is, I cannot get it reproduced by altering the hsearch unit tests.
I'm currently implementing faceted range search support for our DSL, so I need to dynamically build the facet request objects. The fluent API (the Query DSL) is nice to use for specific search queries/facet requests, but building facet requests dynamically leads to not-so-clean code with a lot of conditions on various context objects (or is there some better way to build facet request, still using the Query DSL?)
So, what I'm currently doing is manually create a list of FacetRange objects and use that to build a FacetingRequestImpl manually (had to change the package to org.hibernate.search.query.dsl.impl to be able to use the RangeFacetRequest cons ;)). It seems to work... once, then I get an "org.hibernate.annotations.common.AssertionFailure: Unsupported range type" exception when calling facet manager's getFacets on a 'below' range facet, i.e. [,200].

This exception is thrown at the method: RangeFacetImpl.createNumericRangeQuery(). In this method, it tries to obtain the type by looking at the min object from the FacetRange, which is not set when dealing with a 'below'-facet.

I was unable to find any code that sets this value when using the query dsl, so I expected to see a range type exception on a facet constructed with the query dsl as well.
Or am I overlooking something?


Last edited by Elmer on Thu May 19, 2011 7:44 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: Dynamically construct range facets (on numeric fields)
PostPosted: Thu May 19, 2011 6:38 am 
Beginner
Beginner

Joined: Mon Apr 11, 2011 7:56 am
Posts: 38
Getting closer and got it reproduced. It happens on fields that might have null values. In my case, I have an Integer field (not the primitive type int), which is set to null for some entities. I can get the facets the first time and I can narrow the search results using one of those facets. Then, when calling facetManager.getFacets( facetName ) the second time I get this exception:

Code:
org.hibernate.annotations.common.AssertionFailure: Unsupported range type
   at org.hibernate.search.query.dsl.impl.RangeFacetImpl.createNumericRangeQuery(RangeFacetImpl.java:146)
   at org.hibernate.search.query.dsl.impl.RangeFacetImpl.getFacetQuery(RangeFacetImpl.java:55)
   at org.hibernate.search.query.engine.impl.FacetManagerImpl.createSelectionGroupQuery(FacetManagerImpl.java:160)
   at org.hibernate.search.query.engine.impl.FacetManagerImpl.getFacetFilter(FacetManagerImpl.java:146)
   at org.hibernate.search.query.engine.impl.HSQueryImpl.buildFilters(HSQueryImpl.java:650)
   at org.hibernate.search.query.engine.impl.HSQueryImpl.getQueryHits(HSQueryImpl.java:384)
   at org.hibernate.search.query.engine.impl.HSQueryImpl.queryDocumentExtractor(HSQueryImpl.java:275)
   at org.hibernate.search.query.engine.impl.FacetManagerImpl.getFacets(FacetManagerImpl.java:110)
   at org.hibernate.search.test.query.facet.RangeFacetingTest.testRangeBelowMiddleAbove(RangeFacetingTest.java:159) <-- I modified this test for now


I'll now make a separate unit test to demonstrate the problem.


Top
 Profile  
 
 Post subject: Re: Dynamically construct range facets (on numeric fields)
PostPosted: Thu May 19, 2011 7:04 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
thank you, that would be very useful. When you have it, please create an issue on JIRA and attach it to it.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: Dynamically construct range facets (on numeric fields)
PostPosted: Thu May 19, 2011 7:10 am 
Beginner
Beginner

Joined: Mon Apr 11, 2011 7:56 am
Posts: 38
edit: Created Jira issue HSEARCH-770

Failing test (for testing, add it to org.hibernate.search.test.query.facet.RangeFacetingTest)
Code:
   public void testRangeBelowWithNullValues() {
      final String facetingName = "truckHorsePowerFaceting";
      FacetingRequest rangeRequest = queryBuilder( Truck.class ).facet()
            .name( facetingName )
            .onField( "horsePower" )
            .range()
            .below( 1000 )
            .createFacetingRequest();
      FullTextQuery query = createMatchAllQuery( Truck.class );
      FacetManager facetManager = query.getFacetManager();
      query.getFacetManager().enableFaceting( rangeRequest );

      List<Facet> facets = facetManager.getFacets( facetingName ); //OK
      facets = facetManager.getFacets( facetingName ); //Still OK
      assertFacetCounts( facets, new int[] { 6 } );
      
      facetManager.getFacetGroup( facetingName ).selectFacets( facets.get( 0 ) ); //narrow search on facet
      facets = facetManager.getFacets( facetingName ); //Exception...
      assertFacetCounts( facets, new int[] { 6 } );
      
   }

Change the methods loadTestData and getAnnotatedClasses to:
Code:
   public void loadTestData(Session session) {
      Transaction tx = session.beginTransaction();
      for ( int i = 0; i < albums.length; i++ ) {
         Cd cd = new Cd( albums[i], albumPrices[i], releaseDates[i] );
         session.save( cd );
      }
      for ( int i = 0; i < fruits.length; i++ ) {
         Fruit fruit = new Fruit( fruits[i], fruitPrices[i] );
         session.save( fruit );
      }
      for ( int i = 0; i < horsePowers.length; i++){
         Truck truck = new Truck(horsePowers[i]);
         session.save( truck );
      }
      tx.commit();
      session.clear();
   }

   protected Class<?>[] getAnnotatedClasses() {
      return new Class[] {
            Cd.class,
            Fruit.class,
            Truck.class
      };
   }

Add Truck.java:
Code:
/*
* for testing facetting with Integer fields
*/

package org.hibernate.search.test.query.facet;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.NumericField;

@Entity
@Indexed
public class Truck {
   @Id
   @GeneratedValue
   private int id;

   @Field(index = Index.UN_TOKENIZED)
   @NumericField
   private Integer horsePower;

   private Truck() {
   }
   public Truck(Integer horsePower) {
      this.horsePower = horsePower;
   }
   public int getId() {
      return id;
   }   
   public Integer getHorsePower() {
      return horsePower;
   }
   @Override
   public String toString() {
      final StringBuilder sb = new StringBuilder();
      sb.append( "Truck" );
      sb.append( "{id=" ).append( id );
      sb.append( ", horsePower='" ).append( horsePower );
      sb.append( '}' );
      return sb.toString();
   }
}


Add this line to org.hibernate.search.test.query.facet.AbstractFacetTest
Code:
   public static final Integer[] horsePowers = { 200, 400, 600, null, 1300, null, 730 };


My guess, entities with null values are included in the result of the below facet, so probably null is evaluated to be 'lower' than any valid Integer. The lowest value found is probably used somewhere to set some range during .selectFacets( facetName ). This range is then used again when calling .getFacets( facetingName ), which tries to obtain the type from a null value -> AssertionFailure: Unsupported range type.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.