mirror of https://github.com/apache/lucene.git
LUCENE-5714: BBoxStrategy should convert shapes to bounding box on indexing (but not search)
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1609468 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8e7ad8727c
commit
8f7dc8d07b
|
@ -54,21 +54,22 @@ import org.apache.lucene.util.NumericUtils;
|
||||||
*
|
*
|
||||||
* <h4>Characteristics:</h4>
|
* <h4>Characteristics:</h4>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Only indexes Rectangles; just one per field value.</li>
|
* <li>Only indexes Rectangles; just one per field value. Other shapes can be provided
|
||||||
* <li>Can query only by a Rectangle.</li>
|
* and the bounding box will be used.</li>
|
||||||
* <li>Supports most {@link SpatialOperation}s -- not Overlaps.</li>
|
* <li>Can query only by a Rectangle. Providing other shapes is an error.</li>
|
||||||
|
* <li>Supports most {@link SpatialOperation}s but not Overlaps.</li>
|
||||||
* <li>Uses the DocValues API for any sorting / relevancy.</li>
|
* <li>Uses the DocValues API for any sorting / relevancy.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <h4>Implementation:</h4>
|
* <h4>Implementation:</h4>
|
||||||
* This uses 4 double fields for minX, maxX, minY, maxY
|
* This uses 4 double fields for minX, maxX, minY, maxY
|
||||||
* and a boolean to mark a dateline cross. Depending on the particular {@link
|
* and a boolean to mark a dateline cross. Depending on the particular {@link
|
||||||
* SpatialOperation}s, there is a variety of {@link NumericRangeQuery}s to be
|
* SpatialOperation}s, there are a variety of {@link NumericRangeQuery}s to be
|
||||||
* done.
|
* done.
|
||||||
* The {@link #makeOverlapRatioValueSource(com.spatial4j.core.shape.Rectangle, double)}
|
* The {@link #makeOverlapRatioValueSource(com.spatial4j.core.shape.Rectangle, double)}
|
||||||
* works by calculating the query bbox overlap percentage against the indexed
|
* works by calculating the query bbox overlap percentage against the indexed
|
||||||
* shape overlap percentage. The indexed shape's coordinates are retrieved from
|
* shape overlap percentage. The indexed shape's coordinates are retrieved from
|
||||||
* {@link AtomicReader#getNumericDocValues}
|
* {@link AtomicReader#getNumericDocValues}.
|
||||||
*
|
*
|
||||||
* @lucene.experimental
|
* @lucene.experimental
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +118,9 @@ public class BBoxStrategy extends SpatialStrategy {
|
||||||
return fieldType;
|
return fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Used to customize the indexing options of the 4 number fields, and to a lesser degree the XDL field too. Search
|
||||||
|
* requires indexed=true, and relevancy requires docValues. If these features aren't needed then disable them.
|
||||||
|
* {@link FieldType#freeze()} is called on the argument. */
|
||||||
public void setFieldType(FieldType fieldType) {
|
public void setFieldType(FieldType fieldType) {
|
||||||
fieldType.freeze();
|
fieldType.freeze();
|
||||||
this.fieldType = fieldType;
|
this.fieldType = fieldType;
|
||||||
|
@ -136,17 +140,25 @@ public class BBoxStrategy extends SpatialStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Field[] createIndexableFields(Shape shape) {
|
public Field[] createIndexableFields(Shape shape) {
|
||||||
if (shape instanceof Rectangle)
|
return createIndexableFields(shape.getBoundingBox());
|
||||||
return createIndexableFields((Rectangle)shape);
|
|
||||||
throw new UnsupportedOperationException("Can only index a Rectangle, not " + shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Field subclass circumventing Field limitations. This one instance can optionally index, store,
|
public Field[] createIndexableFields(Rectangle bbox) {
|
||||||
* or have DocValues.
|
Field[] fields = new Field[5];
|
||||||
|
fields[0] = new ComboField(field_minX, bbox.getMinX(), fieldType);
|
||||||
|
fields[1] = new ComboField(field_maxX, bbox.getMaxX(), fieldType);
|
||||||
|
fields[2] = new ComboField(field_minY, bbox.getMinY(), fieldType);
|
||||||
|
fields[3] = new ComboField(field_maxY, bbox.getMaxY(), fieldType);
|
||||||
|
fields[4] = new ComboField(field_xdl, bbox.getCrossesDateLine()?"T":"F", xdlFieldType);
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Field subclass circumventing Field limitations. This one instance can have any combination of indexed, stored,
|
||||||
|
* and docValues.
|
||||||
*/
|
*/
|
||||||
private static class ComboField extends Field {
|
private static class ComboField extends Field {
|
||||||
private ComboField(String name, Object value, FieldType type) {
|
private ComboField(String name, Object value, FieldType type) {
|
||||||
super(name, type);//this expert constructor allows us to have a field that has docValues & indexed
|
super(name, type);//this expert constructor allows us to have a field that has docValues & indexed/stored
|
||||||
super.fieldsData = value;
|
super.fieldsData = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,16 +177,6 @@ public class BBoxStrategy extends SpatialStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field[] createIndexableFields(Rectangle bbox) {
|
|
||||||
Field[] fields = new Field[5];
|
|
||||||
fields[0] = new ComboField(field_minX, bbox.getMinX(), fieldType);
|
|
||||||
fields[1] = new ComboField(field_maxX, bbox.getMaxX(), fieldType);
|
|
||||||
fields[2] = new ComboField(field_minY, bbox.getMinY(), fieldType);
|
|
||||||
fields[3] = new ComboField(field_maxY, bbox.getMaxY(), fieldType);
|
|
||||||
fields[4] = new ComboField(field_xdl, bbox.getCrossesDateLine()?"T":"F", xdlFieldType);
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
// Value Source / Relevancy
|
// Value Source / Relevancy
|
||||||
//---------------------------------
|
//---------------------------------
|
||||||
|
|
|
@ -22,7 +22,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import com.spatial4j.core.context.SpatialContext;
|
import com.spatial4j.core.context.SpatialContext;
|
||||||
import com.spatial4j.core.shape.Point;
|
import com.spatial4j.core.shape.Point;
|
||||||
import com.spatial4j.core.shape.Shape;
|
import com.spatial4j.core.shape.Shape;
|
||||||
import org.apache.lucene.document.Document;
|
|
||||||
import org.apache.lucene.document.FieldType;
|
import org.apache.lucene.document.FieldType;
|
||||||
import org.apache.lucene.spatial.bbox.BBoxStrategy;
|
import org.apache.lucene.spatial.bbox.BBoxStrategy;
|
||||||
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
|
||||||
|
@ -139,14 +138,6 @@ public class DistanceStrategyTest extends StrategyTestCase {
|
||||||
new float[]{1.00f, 0.10f, 0f}, 0.09f);
|
new float[]{1.00f, 0.10f, 0f}, 0.09f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Document newDoc(String id, Shape shape) {
|
|
||||||
//called by adoc(). Make compatible with BBoxStrategy.
|
|
||||||
if (shape != null && strategy instanceof BBoxStrategy)
|
|
||||||
shape = ctx.makeRectangle(shape.getCenter(), shape.getCenter());
|
|
||||||
return super.newDoc(id, shape);
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkDistValueSource(Point pt, float... distances) throws IOException {
|
void checkDistValueSource(Point pt, float... distances) throws IOException {
|
||||||
float multiplier = random().nextFloat() * 100f;
|
float multiplier = random().nextFloat() * 100f;
|
||||||
float[] dists2 = Arrays.copyOf(distances, distances.length);
|
float[] dists2 = Arrays.copyOf(distances, distances.length);
|
||||||
|
|
Loading…
Reference in New Issue