Uploaded image for project: 'Hibernate Search'
  1. HSEARCH-1708

Using DistanceSortField does not verify the field parameter passed to the constructor

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects versions: 5.0.0.Beta1
    • Fix versions: 5.4.0.CR2
    • Components: spatial
    • Labels:

      Description

      It is possible to use DistanceSortField on non existent or non spatial fields without warning or error. From SpatialIndexingTest:

      SpatialIndexingTest.java
      @Test
      public void testNonGeoDistanceSort() throws Exception {
      	NonGeoPOI poi = new NonGeoPOI( 1, "Distance to 24,32 : 0", 24.0d, null, "" );
      	NonGeoPOI poi2 = new NonGeoPOI( 2, "Distance to 24,32 : 24.45", 24.2d, 31.9d, "" );
      	NonGeoPOI poi3 = new NonGeoPOI( 3, "Distance to 24,32 : 10.16", 24.0d, 31.9d, "" );
      	NonGeoPOI poi4 = new NonGeoPOI( 4, "Distance to 24,32 : 15.06", 23.9d, 32.1d, "" );
      	NonGeoPOI poi5 = new NonGeoPOI( 5, "Distance to 24,32 : 11.12", 23.9d, 32.0d, "" );
      	NonGeoPOI poi6 = new NonGeoPOI( 6, "Distance to 24,32 : 22.24", 24.2d, 32.0d, "" );
      	FullTextSession fullTextSession = Search.getFullTextSession( openSession() );
      	Transaction tx = fullTextSession.beginTransaction();
      	fullTextSession.save( poi );
      	fullTextSession.save( poi2 );
      	fullTextSession.save( poi3 );
      	fullTextSession.save( poi4 );
      	fullTextSession.save( poi5 );
      	fullTextSession.save( poi6 );
      	tx.commit();
      	tx = fullTextSession.beginTransaction();
      	double centerLatitude = 24.0d;
      	double centerLongitude = 32.0d;
      	final QueryBuilder builder = fullTextSession.getSearchFactory()
      			.buildQueryBuilder().forEntity( NonGeoPOI.class ).get();
      	org.apache.lucene.search.Query luceneQuery = builder.all().createQuery();
      	FullTextQuery hibQuery = fullTextSession.createFullTextQuery( luceneQuery, NonGeoPOI.class );
      	Sort distanceSort = new Sort( new DistanceSortField( centerLatitude, centerLongitude, "location" ));
      	hibQuery.setSort( distanceSort );
      	hibQuery.setProjection( FullTextQuery.THIS, FullTextQuery.SPATIAL_DISTANCE );
      	hibQuery.setSpatialParameters( centerLatitude, centerLongitude, "location" );
      	List<Object[]> results = hibQuery.list();
      	Double previousDistance = (Double) results.get( 0 )[1];
      	for ( Object[] projectionEntry : results ) {
      		Double currentDistance = (Double) projectionEntry[1];
      		assertTrue( previousDistance + " should be <= " + currentDistance, previousDistance <= currentDistance );
      		previousDistance = currentDistance;
      	}
      	tx.commit();
      }
      

      where NonGeoPOI looks like this:

      NonGeoPOI.java
      @Entity
      @Indexed
      public class NonGeoPOI {
      	@Id
      	Integer id;
      
      	@Field(store = Store.YES)
      	String name;
      
      	@Field(store = Store.YES, index = Index.YES)
      	String type;
      
      	@Field(store = Store.YES, index = Index.YES)
      	@NumericField
      	Double latitude;
      	@Field(store = Store.YES, index = Index.YES)
      	@NumericField
      	Double longitude;
      
      	public NonGeoPOI(Integer id, String name, Double latitude, Double longitude, String type) {
      		this.id = id;
      		this.name = name;
      		this.latitude = latitude;
      		this.longitude = longitude;
      		this.type = type;
      	}
      
      	public NonGeoPOI() {
      	}
      
      	public Integer getId() {
      		return id;
      	}
      
      	public String getName() {
      		return name;
      	}
      
      	public double getLatitude() {
      		return latitude;
      	}
      
      	public double getLongitude() {
      		return longitude;
      	}
      
      	public String getType() {
      		return type;
      	}
      }
      

      The test refers to a field location which does not even exist. The code does neither fail or log a warning. The projected distance value is constant for all indexed points.

      One could try to verify whether the field exists using the meta data, but this requires that the targeted entity is known. What would one do, if all entities are targeted? Does this even make sense?

        Attachments

          Activity

            People

            • Assignee:
              davided Davide D'Alto
              Reporter:
              hardy.ferentschik Hardy Ferentschik
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: