|
|
|
It is possible to use {{DistanceSortField}} on non existent or non spatial fields without warning or error. From {{SpatialIndexingTest}}:
{code:title=SpatialIndexingTest.java|borderStyle=solid} @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(); } {code}
where {{NonGeoPOI}} looks like this:
{code:title=NonGeoPOI.java|borderStyle=solid} @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; } } {code}
The test refers to a filed {{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?
|
|
|
|