@Transient @Field @FieldBridge(impl = SpatialFieldBridgeByRange.class) public Coordinates getLocation() { if (latitude == null || longitude == null) { return null; } Coordinates point = Point.fromDegrees(latitude, longitude); return point; }
/** * Actual overridden method that does the indexing * * @param name of the field * @param value of the field * @param document document being indexed * @param luceneOptions current indexing options and accessors */ @Override public void set(String name, Object value, Document document, LuceneOptions luceneOptions) { if (value != null) { Double latitude = getLatitude(value); Double longitude = getLongitude(value); if ((latitude != null) && (longitude != null)) { if (spatialHashIndex) { Point point = Point.fromDegrees(latitude, longitude); for (int i = topSpatialHashLevel; i <= bottomSpatialHashLevel; i++) { luceneOptions.addFieldToDocument( SpatialHelper.formatFieldName(i, name), SpatialHelper.getSpatialHashCellId(point, i), document); } } if (numericFieldsIndex) { final String latitudeFieldName = SpatialHelper.formatLatitude(name); final String longitudeFieldName = SpatialHelper.formatLongitude(name); luceneOptions.addNumericFieldToDocument(latitudeFieldName, latitude, document); luceneOptions.addNumericFieldToDocument(longitudeFieldName, longitude, document); Field latitudeDocValuesField = new SpatialNumericDocValueField(latitudeFieldName, latitude); document.add(latitudeDocValuesField); Field longitudeDocValuesField = new SpatialNumericDocValueField(longitudeFieldName, longitude); document.add(longitudeDocValuesField); } } } }
@Test public void testSpatialQueries() { Transaction transaction = fullTextSession.beginTransaction(); final QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(POI.class).get(); Coordinates coordinates = Point.fromDegrees(24d, 31.5d); Query query = builder .spatial() .onField("location") .within(51, Unit.KM) .ofCoordinates(coordinates) .createQuery(); List<?> results = fullTextSession.createFullTextQuery(query, POI.class).list(); assertEquals("test spatial hash based spatial query", 1, results.size()); assertEquals("test spatial hash based spatial query", "Bozo", ((POI) results.get(0)).getName()); query = builder .spatial() .onField("location") .within(500, Unit.KM) .ofLatitude(48.858333d) .andLongitude(2.294444d) .createQuery(); results = fullTextSession.createFullTextQuery(query, POI.class).list(); assertEquals("test spatial hash based spatial query", 1, results.size()); assertEquals( "test spatial hash based spatial query", "Tour Eiffel", ((POI) results.get(0)).getName()); transaction.commit(); }
public static void FacetTest() { Session session = null; FullTextSession fullTextSession = null; SessionFactory sessionFactory = null; try { sessionFactory = new Configuration().configure(hibernateConfigurationFile).buildSessionFactory(); session = sessionFactory.openSession(); session.beginTransaction(); fullTextSession = Search.getFullTextSession(session); org.apache.lucene.search.Query luceneQuery; FullTextQuery hibQuery; Point center = Point.fromDegrees(46, 4); double radius = 50.0d; luceneQuery = SpatialQueryBuilderFromPoint.buildSpatialQueryByGrid(center, radius, "location"); hibQuery = fullTextSession.createFullTextQuery(luceneQuery, POI.class); hibQuery.setProjection("id", "name", "type"); FacetManager facetManager = hibQuery.getFacetManager(); QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(POI.class).get(); FacetingRequest facetingRequest = queryBuilder .facet() .name("typeFacet") .onField("type") .discrete() .orderedBy(FacetSortOrder.COUNT_DESC) .includeZeroCounts(false) .createFacetingRequest(); facetManager.enableFaceting(facetingRequest); Integer size = hibQuery.getResultSize(); List list = hibQuery.list(); List<Facet> facets = facetManager.getFacets("typeFacet"); System.out.println(facets); session.getTransaction().commit(); session.close(); sessionFactory.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (fullTextSession != null && fullTextSession.isOpen()) { Transaction transaction = fullTextSession.getTransaction(); if (transaction != null && transaction.isActive()) { transaction.rollback(); } fullTextSession.close(); } if (sessionFactory != null && !sessionFactory.isClosed()) { sessionFactory.close(); } } }
public static void Bench() { Session session = null; FullTextSession fullTextSession = null; SessionFactory sessionFactory = null; try { sessionFactory = new Configuration().configure(hibernateConfigurationFile).buildSessionFactory(); session = sessionFactory.openSession(); session.beginTransaction(); fullTextSession = Search.getFullTextSession(session); long gridTotalDuration = 0; long spatialTotalDuration = 0; long doubleRangeTotalDuration = 0; long distanceDoubleRangeTotalDuration = 0; long gridDocsFetched = 0; long spatialDocsFetched = 0; long doubleRangeDocsFetched = 0; long distanceDoubleRangeDocsFetched = 0; org.apache.lucene.search.Query luceneQuery; long startTime, endTime, duration; FullTextQuery hibQuery; List gridResults, rangeResults; final QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(POI.class).get(); org.apache.lucene.search.Query query; final Integer iterations = 2000; final Integer warmUp = 50; Random random = new Random(42); for (int i = 0; i < iterations; i++) { Point center = Point.fromDegrees(random.nextDouble() * 2 + 44, random.nextDouble() * 2 + 3); double radius = 25.0d; Rectangle boundingBox = Rectangle.fromBoundingCircle(center, radius); query = queryBuilder .bool() .must( queryBuilder .range() .onField("latitude") .from(boundingBox.getLowerLeft().getLatitude()) .to(boundingBox.getUpperRight().getLatitude()) .createQuery()) .must( queryBuilder .range() .onField("longitude") .from(boundingBox.getLowerLeft().getLongitude()) .to(boundingBox.getUpperRight().getLongitude()) .createQuery()) .createQuery(); hibQuery = fullTextSession.createFullTextQuery(query, POI.class); hibQuery.setProjection("id", "name"); startTime = System.nanoTime(); try { doubleRangeDocsFetched += hibQuery.getResultSize(); } finally { endTime = System.nanoTime(); } duration = endTime - startTime; if (i > warmUp) { doubleRangeTotalDuration += duration; } session.clear(); query = queryBuilder .bool() .must( queryBuilder .range() .onField("latitude") .from(boundingBox.getLowerLeft().getLatitude()) .to(boundingBox.getUpperRight().getLatitude()) .createQuery()) .must( queryBuilder .range() .onField("longitude") .from(boundingBox.getLowerLeft().getLongitude()) .to(boundingBox.getUpperRight().getLongitude()) .createQuery()) .createQuery(); org.apache.lucene.search.Query filteredQuery = new ConstantScoreQuery( SpatialQueryBuilderFromPoint.buildDistanceFilter( new QueryWrapperFilter(query), center, radius, "location")); hibQuery = fullTextSession.createFullTextQuery(filteredQuery, POI.class); hibQuery.setProjection("id", "name"); startTime = System.nanoTime(); try { distanceDoubleRangeDocsFetched += hibQuery.getResultSize(); } finally { endTime = System.nanoTime(); } duration = endTime - startTime; if (i > warmUp) { distanceDoubleRangeTotalDuration += duration; } rangeResults = hibQuery.list(); session.clear(); luceneQuery = SpatialQueryBuilderFromPoint.buildGridQuery(center, radius, "location"); hibQuery = fullTextSession.createFullTextQuery(luceneQuery, POI.class); hibQuery.setProjection("id", "name"); startTime = System.nanoTime(); try { gridDocsFetched += hibQuery.getResultSize(); } finally { endTime = System.nanoTime(); } duration = endTime - startTime; if (i > warmUp) { gridTotalDuration += duration; } session.clear(); luceneQuery = SpatialQueryBuilderFromPoint.buildSpatialQueryByGrid(center, radius, "location"); hibQuery = fullTextSession.createFullTextQuery(luceneQuery, POI.class); hibQuery.setProjection("id", "name"); startTime = System.nanoTime(); try { spatialDocsFetched += hibQuery.getResultSize(); } finally { endTime = System.nanoTime(); } duration = endTime - startTime; if (i > warmUp) { spatialTotalDuration += duration; } gridResults = hibQuery.list(); session.clear(); if (rangeResults.size() != gridResults.size()) { luceneQuery = SpatialQueryBuilderFromPoint.buildDistanceQuery(center, radius, "location"); hibQuery = fullTextSession.createFullTextQuery(luceneQuery, POI.class); hibQuery.setProjection("id", "name"); System.out.println( ">>>>> Different numbers of documents fetched for point (" + Double.toString(center.getLatitude()) + "," + Double.toString(center.getLongitude()) + ") and radius " + Double.toString(radius)); System.out.println("Range results : " + rangeResults); System.out.println("Grid results : " + gridResults); System.out.println("Pure distance results : " + hibQuery.getResultSize()); List<Integer> rangeIds = new ArrayList<Integer>(); for (int index = 0; index < rangeResults.size(); index++) { rangeIds.add((Integer) ((Object[]) rangeResults.get(index))[0]); } List<Integer> gridIds = new ArrayList<Integer>(); for (int index = 0; index < gridResults.size(); index++) { gridIds.add((Integer) ((Object[]) gridResults.get(index))[0]); } rangeIds.removeAll(gridIds); System.out.println("Missing Ids : " + rangeIds); } } session.getTransaction().commit(); session.close(); sessionFactory.close(); System.out.println( "Mean time with Grid : " + Double.toString( (double) gridTotalDuration * Math.pow(10, -6) / (iterations - warmUp)) + " ms. Average number of docs fetched : " + Double.toString(gridDocsFetched / ((iterations - warmUp) * 1.0d))); System.out.println( "Mean time with Grid + Distance filter : " + Double.toString( (double) spatialTotalDuration * Math.pow(10, -6) / (iterations - warmUp)) + " ms. Average number of docs fetched : " + Double.toString(spatialDocsFetched / ((iterations - warmUp) * 1.0d))); System.out.println( "Mean time with DoubleRange : " + Double.toString( (double) doubleRangeTotalDuration * Math.pow(10, -6) / (iterations - warmUp)) + " ms. Average number of docs fetched : " + Double.toString(doubleRangeDocsFetched / ((iterations - warmUp) * 1.0d))); System.out.println( "Mean time with DoubleRange + Distance filter : " + Double.toString( (double) distanceDoubleRangeTotalDuration * Math.pow(10, -6) / (iterations - warmUp)) + " ms. Average number of docs fetched : " + Double.toString(distanceDoubleRangeDocsFetched / ((iterations - warmUp) * 1.0d))); } catch (Exception e) { e.printStackTrace(); } finally { if (fullTextSession != null && fullTextSession.isOpen()) { Transaction transaction = fullTextSession.getTransaction(); if (transaction != null && transaction.isActive()) { transaction.rollback(); } fullTextSession.close(); } if (sessionFactory != null && !sessionFactory.isClosed()) { sessionFactory.close(); } } }