LUCENE-6904: rewrite GeoPointInBBoxQuery to FieldValueQuery when min/max lon/lat values are set to limits.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1715957 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Knize 2015-11-23 21:23:57 +00:00
parent 160cf90742
commit bc01212d1a
3 changed files with 21 additions and 2 deletions

View File

@ -104,6 +104,9 @@ public final class GeoPointField extends Field {
if (type.numericType() != FieldType.NumericType.LONG) { if (type.numericType() != FieldType.NumericType.LONG) {
throw new IllegalArgumentException("type.numericType() must be LONG but got " + type.numericType()); throw new IllegalArgumentException("type.numericType() must be LONG but got " + type.numericType());
} }
if (type.docValuesType() != DocValuesType.SORTED_NUMERIC) {
throw new IllegalArgumentException("type.docValuesType() must be SORTED_NUMERIC but got " + type.docValuesType());
}
fieldsData = GeoUtils.mortonHash(lon, lat); fieldsData = GeoUtils.mortonHash(lon, lat);
} }

View File

@ -18,6 +18,7 @@ package org.apache.lucene.search;
*/ */
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.util.GeoUtils;
/** Implements a simple bounding box query on a GeoPoint field. This is inspired by /** Implements a simple bounding box query on a GeoPoint field. This is inspired by
* {@link org.apache.lucene.search.NumericRangeQuery} and is implemented using a * {@link org.apache.lucene.search.NumericRangeQuery} and is implemented using a
@ -55,6 +56,13 @@ public class GeoPointInBBoxQuery extends Query {
@Override @Override
public Query rewrite(IndexReader reader) { public Query rewrite(IndexReader reader) {
// short-circuit to match all if specifying the whole map
if (minLon == GeoUtils.MIN_LON_INCL && maxLon == GeoUtils.MAX_LON_INCL
&& minLat == GeoUtils.MIN_LAT_INCL && maxLat == GeoUtils.MAX_LAT_INCL) {
// FieldValueQuery is valid since DocValues are *required* for GeoPointField
return new FieldValueQuery(field);
}
if (maxLon < minLon) { if (maxLon < minLon) {
BooleanQuery.Builder bqb = new BooleanQuery.Builder(); BooleanQuery.Builder bqb = new BooleanQuery.Builder();

View File

@ -22,6 +22,7 @@ import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType; import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.GeoPointField; import org.apache.lucene.document.GeoPointField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.store.Directory; import org.apache.lucene.store.Directory;
@ -103,7 +104,7 @@ public class TestGeoPointQuery extends BaseGeoPointTestCase {
new GeoPointField(FIELD_NAME, -83.99724648980559, 58.29438379542874, storedPoint), new GeoPointField(FIELD_NAME, -83.99724648980559, 58.29438379542874, storedPoint),
new GeoPointField(FIELD_NAME, -26.779373834241003, 33.541429799076354, storedPoint), new GeoPointField(FIELD_NAME, -26.779373834241003, 33.541429799076354, storedPoint),
new GeoPointField(FIELD_NAME, -77.35379276106497, 26.774024500421728, storedPoint), new GeoPointField(FIELD_NAME, -77.35379276106497, 26.774024500421728, storedPoint),
new GeoPointField(FIELD_NAME, -14.796283808944777, -62.455081198245665, storedPoint), new GeoPointField(FIELD_NAME, -14.796283808944777, -90.0, storedPoint),
new GeoPointField(FIELD_NAME, -178.8538113027811, 32.94823588839368, storedPoint), new GeoPointField(FIELD_NAME, -178.8538113027811, 32.94823588839368, storedPoint),
new GeoPointField(FIELD_NAME, 178.8538113027811, 32.94823588839368, storedPoint), new GeoPointField(FIELD_NAME, 178.8538113027811, 32.94823588839368, storedPoint),
new GeoPointField(FIELD_NAME, -73.998776, 40.720611, storedPoint), new GeoPointField(FIELD_NAME, -73.998776, 40.720611, storedPoint),
@ -123,6 +124,13 @@ public class TestGeoPointQuery extends BaseGeoPointTestCase {
writer.addDocument(doc); writer.addDocument(doc);
} }
// index random string documents
for (int i=0; i<random().nextInt(10); ++i) {
Document doc = new Document();
doc.add(new StringField("string", Integer.toString(i), Field.Store.NO));
writer.addDocument(doc);
}
reader = writer.getReader(); reader = writer.getReader();
searcher = newSearcher(reader); searcher = newSearcher(reader);
writer.close(); writer.close();
@ -264,7 +272,7 @@ public class TestGeoPointQuery extends BaseGeoPointTestCase {
} }
public void testWholeMap() throws Exception { public void testWholeMap() throws Exception {
TopDocs td = bboxQuery(-179.9, -89.9, 179.9, 89.9, 20); TopDocs td = bboxQuery(GeoUtils.MIN_LON_INCL, GeoUtils.MIN_LAT_INCL, GeoUtils.MAX_LON_INCL, GeoUtils.MAX_LAT_INCL, 20);
assertEquals("testWholeMap failed", 24, td.totalHits); assertEquals("testWholeMap failed", 24, td.totalHits);
} }