You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by nk...@apache.org on 2016/03/31 01:30:16 UTC
lucene-solr:branch_6_0: * LUCENE-7094: BBoxStrategy and
PointVectorStrategy now support PointValues (in addition to legacy numeric
trie). Their APIs were changed a little and also made more consistent.
PointValues/Trie is optional, DocValues is optiona
Repository: lucene-solr
Updated Branches:
refs/heads/branch_6_0 479f0e063 -> f9da81644
* LUCENE-7094: BBoxStrategy and PointVectorStrategy now support PointValues (in addition to legacy numeric trie). Their APIs were changed a little and also made more consistent. PointValues/Trie is optional, DocValues is optional, stored value is optional.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f9da8164
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f9da8164
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f9da8164
Branch: refs/heads/branch_6_0
Commit: f9da8164483912cad40032387783f07e8c0cfc73
Parents: 479f0e0
Author: nknize <nk...@apache.org>
Authored: Wed Mar 30 18:14:20 2016 -0500
Committer: nknize <nk...@apache.org>
Committed: Wed Mar 30 18:16:02 2016 -0500
----------------------------------------------------------------------
lucene/CHANGES.txt | 6 +
.../lucene/spatial/bbox/BBoxStrategy.java | 318 +++++++++++++------
.../spatial/vector/PointVectorStrategy.java | 177 +++++++++--
.../lucene/spatial/DistanceStrategyTest.java | 40 +--
.../apache/lucene/spatial/PortedSolr3Test.java | 13 +-
.../lucene/spatial/QueryEqualsHashCodeTest.java | 10 +-
.../apache/lucene/spatial/SpatialTestCase.java | 42 +--
.../lucene/spatial/bbox/TestBBoxStrategy.java | 68 ++--
.../composite/CompositeStrategyTest.java | 17 +-
.../serialized/SerializedStrategyTest.java | 7 +-
.../lucene/spatial/spatial4j/Geo3dRptTest.java | 15 +-
.../spatial/vector/TestPointVectorStrategy.java | 55 +++-
.../java/org/apache/solr/schema/BBoxField.java | 6 +-
.../schema/SpatialPointVectorFieldType.java | 23 +-
14 files changed, 528 insertions(+), 269 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index f7f18b9..751116b 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -70,6 +70,12 @@ New Features
API Changes
+* LUCENE-7094: BBoxStrategy and PointVectorStrategy now support
+ PointValues (in addition to legacy numeric trie). Their APIs
+ were changed a little and also made more consistent. PointValues/Trie
+ is optional, DocValues is optional, stored value is optional.
+ (Nick Knize, David Smiley)
+
* LUCENE-6067: Accountable.getChildResources has a default
implementation returning the empty list. (Robert Muir)
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
index 253b290..63a1138 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/bbox/BBoxStrategy.java
@@ -16,15 +16,15 @@
*/
package org.apache.lucene.spatial.bbox;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Rectangle;
-import org.locationtech.spatial4j.shape.Shape;
-import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.DoubleDocValuesField;
+import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.DocValuesType;
+import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.Term;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.BooleanClause;
@@ -41,6 +41,10 @@ import org.apache.lucene.spatial.util.DistanceToShapeValueSource;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.LegacyNumericUtils;
import org.apache.lucene.util.NumericUtils;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Rectangle;
+import org.locationtech.spatial4j.shape.Shape;
/**
@@ -63,7 +67,7 @@ import org.apache.lucene.util.NumericUtils;
* <p>
* This uses 4 double fields for minX, maxX, minY, maxY
* and a boolean to mark a dateline cross. Depending on the particular {@link
- * SpatialOperation}s, there are a variety of {@link org.apache.lucene.search.LegacyNumericRangeQuery}s to be
+ * SpatialOperation}s, there are a variety of range queries on {@link DoublePoint}s to be
* done.
* The {@link #makeOverlapRatioValueSource(org.locationtech.spatial4j.shape.Rectangle, double)}
* works by calculating the query bbox overlap percentage against the indexed
@@ -74,6 +78,35 @@ import org.apache.lucene.util.NumericUtils;
*/
public class BBoxStrategy extends SpatialStrategy {
+ // note: we use a FieldType to articulate the options we want on the field. We don't use it as-is with a Field, we
+ // create more than one Field.
+
+ /**
+ * pointValues, docValues, and nothing else.
+ */
+ public static FieldType DEFAULT_FIELDTYPE;
+
+ @Deprecated
+ public static FieldType LEGACY_FIELDTYPE;
+ static {
+ // Default: pointValues + docValues
+ FieldType type = new FieldType();
+ type.setDimensions(1, Double.BYTES);//pointValues (assume Double)
+ type.setDocValuesType(DocValuesType.NUMERIC);//docValues
+ type.setStored(false);
+ type.freeze();
+ DEFAULT_FIELDTYPE = type;
+ // Legacy default: legacyNumerics + docValues
+ type = new FieldType();
+ type.setIndexOptions(IndexOptions.DOCS);
+ type.setNumericType(FieldType.LegacyNumericType.DOUBLE);
+ type.setNumericPrecisionStep(8);// same as solr default
+ type.setDocValuesType(DocValuesType.NUMERIC);//docValues
+ type.setStored(false);
+ type.freeze();
+ LEGACY_FIELDTYPE = type;
+ }
+
public static final String SUFFIX_MINX = "__minX";
public static final String SUFFIX_MAXX = "__maxX";
public static final String SUFFIX_MINY = "__minY";
@@ -84,17 +117,45 @@ public class BBoxStrategy extends SpatialStrategy {
* The Bounding Box gets stored as four fields for x/y min/max and a flag
* that says if the box crosses the dateline (xdl).
*/
- protected final String field_bbox;
- protected final String field_minX;
- protected final String field_minY;
- protected final String field_maxX;
- protected final String field_maxY;
- protected final String field_xdl; // crosses dateline
+ final String field_bbox;
+ final String field_minX;
+ final String field_minY;
+ final String field_maxX;
+ final String field_maxY;
+ final String field_xdl; // crosses dateline
+
+ private final FieldType optionsFieldType;//from constructor; aggregate field type used to express all options
+ private final int fieldsLen;
+ private final boolean hasStored;
+ private final boolean hasDocVals;
+ private final boolean hasPointVals;
+ // equiv to "hasLegacyNumerics":
+ private final FieldType legacyNumericFieldType; // not stored; holds precision step.
+ private final FieldType xdlFieldType;
- protected FieldType fieldType;//for the 4 numbers
- protected FieldType xdlFieldType;
+ /**
+ * Creates a new {@link BBoxStrategy} instance that uses {@link DoublePoint} and {@link DoublePoint#newRangeQuery}
+ */
+ public static BBoxStrategy newInstance(SpatialContext ctx, String fieldNamePrefix) {
+ return new BBoxStrategy(ctx, fieldNamePrefix, DEFAULT_FIELDTYPE);
+ }
+
+ /**
+ * Creates a new {@link BBoxStrategy} instance that uses {@link LegacyDoubleField} for backwards compatibility
+ * @deprecated LegacyNumerics will be removed
+ */
+ @Deprecated
+ public static BBoxStrategy newLegacyInstance(SpatialContext ctx, String fieldNamePrefix) {
+ return new BBoxStrategy(ctx, fieldNamePrefix, LEGACY_FIELDTYPE);
+ }
- public BBoxStrategy(SpatialContext ctx, String fieldNamePrefix) {
+ /**
+ * Creates this strategy.
+ * {@code fieldType} is used to customize the indexing options of the 4 number fields, and to a lesser degree the XDL
+ * field too. Search requires pointValues (or legacy numerics), and relevancy requires docValues. If these features
+ * aren't needed then disable them.
+ */
+ public BBoxStrategy(SpatialContext ctx, String fieldNamePrefix, FieldType fieldType) {
super(ctx, fieldNamePrefix);
field_bbox = fieldNamePrefix;
field_minX = fieldNamePrefix + SUFFIX_MINX;
@@ -103,34 +164,49 @@ public class BBoxStrategy extends SpatialStrategy {
field_maxY = fieldNamePrefix + SUFFIX_MAXY;
field_xdl = fieldNamePrefix + SUFFIX_XDL;
- FieldType fieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
- fieldType.setNumericPrecisionStep(8);//Solr's default
- fieldType.setDocValuesType(DocValuesType.NUMERIC);
- setFieldType(fieldType);
- }
+ fieldType.freeze();
+ this.optionsFieldType = fieldType;
- private int getPrecisionStep() {
- return fieldType.numericPrecisionStep();
- }
+ int numQuads = 0;
+ if ((this.hasStored = fieldType.stored())) {
+ numQuads++;
+ }
+ if ((this.hasDocVals = fieldType.docValuesType() != DocValuesType.NONE)) {
+ numQuads++;
+ }
+ if ((this.hasPointVals = fieldType.pointDimensionCount() > 0)) {
+ numQuads++;
+ }
+ if (fieldType.indexOptions() != IndexOptions.NONE && fieldType.numericType() != null) {
+ if (hasPointVals) {
+ throw new IllegalArgumentException("pointValues and LegacyNumericType are mutually exclusive");
+ }
+ if (fieldType.numericType() != FieldType.LegacyNumericType.DOUBLE) {
+ throw new IllegalArgumentException(getClass() + " does not support " + fieldType.numericType());
+ }
+ numQuads++;
+ legacyNumericFieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
+ legacyNumericFieldType.setNumericPrecisionStep(fieldType.numericPrecisionStep());
+ legacyNumericFieldType.freeze();
+ } else {
+ legacyNumericFieldType = null;
+ }
- public FieldType getFieldType() {
- return fieldType;
+ if (hasPointVals || legacyNumericFieldType != null) { // if we have an index...
+ xdlFieldType = new FieldType(StringField.TYPE_NOT_STORED);
+ xdlFieldType.setIndexOptions(IndexOptions.DOCS);
+ xdlFieldType.freeze();
+ } else {
+ xdlFieldType = null;
+ }
+
+ this.fieldsLen = numQuads * 4 + (xdlFieldType != null ? 1 : 0);
}
- /** 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) {
- fieldType.freeze();
- this.fieldType = fieldType;
- //only double's supported right now
- if (fieldType.numericType() != FieldType.LegacyNumericType.DOUBLE)
- throw new IllegalArgumentException("BBoxStrategy only supports doubles at this time.");
- //for xdlFieldType, copy some similar options. Don't do docValues since it isn't needed here.
- xdlFieldType = new FieldType(StringField.TYPE_NOT_STORED);
- xdlFieldType.setStored(fieldType.stored());
- xdlFieldType.setIndexOptions(fieldType.indexOptions());
- xdlFieldType.freeze();
+ /** Returns a field type representing the set of field options. This is identical to what was passed into the
+ * constructor. It's frozen. */
+ public FieldType getFieldType() {
+ return optionsFieldType;
}
//---------------------------------
@@ -142,40 +218,41 @@ public class BBoxStrategy extends SpatialStrategy {
return createIndexableFields(shape.getBoundingBox());
}
- 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;
- }
-
- /** Field subclass circumventing Field limitations. This one instance can have any combination of indexed, stored,
- * and docValues.
- */
- private static class ComboField extends Field {
- private ComboField(String name, Object value, FieldType type) {
- super(name, type);//this expert constructor allows us to have a field that has docValues & indexed/stored
- super.fieldsData = value;
+ private Field[] createIndexableFields(Rectangle bbox) {
+ Field[] fields = new Field[fieldsLen];
+ int idx = -1;
+ if (hasStored) {
+ fields[++idx] = new StoredField(field_minX, bbox.getMinX());
+ fields[++idx] = new StoredField(field_minY, bbox.getMinY());
+ fields[++idx] = new StoredField(field_maxX, bbox.getMaxX());
+ fields[++idx] = new StoredField(field_maxY, bbox.getMaxY());
}
-
- //Is this a hack? We assume that numericValue() is only called for DocValues purposes.
- @Override
- public Number numericValue() {
- //Numeric DocValues only supports Long,
- final Number number = super.numericValue();
- if (number == null)
- return null;
- if (fieldType().numericType() == FieldType.LegacyNumericType.DOUBLE)
- return Double.doubleToLongBits(number.doubleValue());
- if (fieldType().numericType() == FieldType.LegacyNumericType.FLOAT)
- return Float.floatToIntBits(number.floatValue());
- return number.longValue();
+ if (hasDocVals) {
+ fields[++idx] = new DoubleDocValuesField(field_minX, bbox.getMinX());
+ fields[++idx] = new DoubleDocValuesField(field_minY, bbox.getMinY());
+ fields[++idx] = new DoubleDocValuesField(field_maxX, bbox.getMaxX());
+ fields[++idx] = new DoubleDocValuesField(field_maxY, bbox.getMaxY());
}
+ if (hasPointVals) {
+ fields[++idx] = new DoublePoint(field_minX, bbox.getMinX());
+ fields[++idx] = new DoublePoint(field_minY, bbox.getMinY());
+ fields[++idx] = new DoublePoint(field_maxX, bbox.getMaxX());
+ fields[++idx] = new DoublePoint(field_maxY, bbox.getMaxY());
+ }
+ if (legacyNumericFieldType != null) {
+ fields[++idx] = new LegacyDoubleField(field_minX, bbox.getMinX(), legacyNumericFieldType);
+ fields[++idx] = new LegacyDoubleField(field_minY, bbox.getMinY(), legacyNumericFieldType);
+ fields[++idx] = new LegacyDoubleField(field_maxX, bbox.getMaxX(), legacyNumericFieldType);
+ fields[++idx] = new LegacyDoubleField(field_maxY, bbox.getMaxY(), legacyNumericFieldType);
+ }
+ if (xdlFieldType != null) {
+ fields[++idx] = new Field(field_xdl, bbox.getCrossesDateLine()?"T":"F", xdlFieldType);
+ }
+ assert idx == fields.length - 1;
+ return fields;
}
+
//---------------------------------
// Value Source / Relevancy
//---------------------------------
@@ -253,8 +330,8 @@ public class BBoxStrategy extends SpatialStrategy {
// Y conditions
// docMinY <= queryExtent.getMinY() AND docMaxY >= queryExtent.getMaxY()
- Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), null, bbox.getMinY(), false, true);
- Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), bbox.getMaxY(), null, true, false);
+ Query qMinY = this.makeNumericRangeQuery(field_minY, null, bbox.getMinY(), false, true);
+ Query qMaxY = this.makeNumericRangeQuery(field_maxY, bbox.getMaxY(), null, true, false);
Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
// X conditions
@@ -266,8 +343,8 @@ public class BBoxStrategy extends SpatialStrategy {
// X Conditions for documents that do not cross the date line,
// documents that contain the min X and max X of the query envelope,
// docMinX <= queryExtent.getMinX() AND docMaxX >= queryExtent.getMaxX()
- Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
- Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+ Query qMinX = this.makeNumericRangeQuery(field_minX, null, bbox.getMinX(), false, true);
+ Query qMaxX = this.makeNumericRangeQuery(field_maxX, bbox.getMaxX(), null, true, false);
Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
Query qNonXDL = this.makeXDL(false, qMinMax);
@@ -278,8 +355,8 @@ public class BBoxStrategy extends SpatialStrategy {
// the left portion of the document contains the min X of the query
// OR the right portion of the document contains the max X of the query,
// docMinXLeft <= queryExtent.getMinX() OR docMaxXRight >= queryExtent.getMaxX()
- Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
- Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+ Query qXDLLeft = this.makeNumericRangeQuery(field_minX, null, bbox.getMinX(), false, true);
+ Query qXDLRight = this.makeNumericRangeQuery(field_maxX, bbox.getMaxX(), null, true, false);
Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.SHOULD, qXDLLeft, qXDLRight);
Query qXDL = this.makeXDL(true, qXDLLeftRight);
@@ -302,8 +379,8 @@ public class BBoxStrategy extends SpatialStrategy {
// the left portion of the document contains the min X of the query
// AND the right portion of the document contains the max X of the query,
// docMinXLeft <= queryExtent.getMinX() AND docMaxXRight >= queryExtent.getMaxX()
- Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), null, bbox.getMinX(), false, true);
- Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), bbox.getMaxX(), null, true, false);
+ Query qXDLLeft = this.makeNumericRangeQuery(field_minX, null, bbox.getMinX(), false, true);
+ Query qXDLRight = this.makeNumericRangeQuery(field_maxX, bbox.getMaxX(), null, true, false);
Query qXDLLeftRight = this.makeXDL(true, this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight));
Query qWorld = makeQuery(BooleanClause.Occur.MUST,
@@ -328,8 +405,8 @@ public class BBoxStrategy extends SpatialStrategy {
// Y conditions
// docMinY > queryExtent.getMaxY() OR docMaxY < queryExtent.getMinY()
- Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMaxY(), null, false, false);
- Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMinY(), false, false);
+ Query qMinY = this.makeNumericRangeQuery(field_minY, bbox.getMaxY(), null, false, false);
+ Query qMaxY = this.makeNumericRangeQuery(field_maxY, null, bbox.getMinY(), false, false);
Query yConditions = this.makeQuery(BooleanClause.Occur.SHOULD, qMinY, qMaxY);
// X conditions
@@ -340,14 +417,15 @@ public class BBoxStrategy extends SpatialStrategy {
// X Conditions for documents that do not cross the date line,
// docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()
- Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
+ Query qMinX = this.makeNumericRangeQuery(field_minX, bbox.getMaxX(), null, false, false);
if (bbox.getMinX() == -180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
BooleanQuery.Builder bq = new BooleanQuery.Builder();
bq.add(qMinX, BooleanClause.Occur.MUST);
bq.add(makeNumberTermQuery(field_maxX, 180.0), BooleanClause.Occur.MUST_NOT);
qMinX = bq.build();
}
- Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
+ Query qMaxX = this.makeNumericRangeQuery(field_maxX, null, bbox.getMinX(), false, false);
+
if (bbox.getMaxX() == 180.0 && ctx.isGeo()) {//touches dateline; -180 == 180
BooleanQuery.Builder bq = new BooleanQuery.Builder();
bq.add(qMaxX, BooleanClause.Occur.MUST);
@@ -368,8 +446,8 @@ public class BBoxStrategy extends SpatialStrategy {
// where: docMaxXLeft = 180.0, docMinXRight = -180.0
// (docMaxXLeft < queryExtent.getMinX()) equates to (180.0 < queryExtent.getMinX()) and is ignored
// (docMinXRight > queryExtent.getMaxX()) equates to (-180.0 > queryExtent.getMaxX()) and is ignored
- Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
- Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
+ Query qMinXLeft = this.makeNumericRangeQuery(field_minX, bbox.getMaxX(), null, false, false);
+ Query qMaxXRight = this.makeNumericRangeQuery(field_maxX, null, bbox.getMinX(), false, false);
Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXRight);
Query qXDL = this.makeXDL(true, qLeftRight);
@@ -383,10 +461,10 @@ public class BBoxStrategy extends SpatialStrategy {
// the document must be disjoint to both the left and right query portions
// (docMinX > queryExtent.getMaxX()Left OR docMaxX < queryExtent.getMinX()) AND (docMinX > queryExtent.getMaxX() OR docMaxX < queryExtent.getMinX()Left)
// where: queryExtent.getMaxX()Left = 180.0, queryExtent.getMinX()Left = -180.0
- Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), 180.0, null, false, false);
- Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMinX(), false, false);
- Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMaxX(), null, false, false);
- Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, -180.0, false, false);
+ Query qMinXLeft = this.makeNumericRangeQuery(field_minX, 180.0, null, false, false);
+ Query qMaxXLeft = this.makeNumericRangeQuery(field_maxX, null, bbox.getMinX(), false, false);
+ Query qMinXRight = this.makeNumericRangeQuery(field_minX, bbox.getMaxX(), null, false, false);
+ Query qMaxXRight = this.makeNumericRangeQuery(field_maxX, null, -180.0, false, false);
Query qLeft = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXLeft, qMaxXLeft);
Query qRight = this.makeQuery(BooleanClause.Occur.SHOULD, qMinXRight, qMaxXRight);
Query qLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qLeft, qRight);
@@ -478,8 +556,8 @@ public class BBoxStrategy extends SpatialStrategy {
// Y conditions
// docMinY >= queryExtent.getMinY() AND docMaxY <= queryExtent.getMaxY()
- Query qMinY = LegacyNumericRangeQuery.newDoubleRange(field_minY, getPrecisionStep(), bbox.getMinY(), null, true, false);
- Query qMaxY = LegacyNumericRangeQuery.newDoubleRange(field_maxY, getPrecisionStep(), null, bbox.getMaxY(), false, true);
+ Query qMinY = this.makeNumericRangeQuery(field_minY, bbox.getMinY(), null, true, false);
+ Query qMaxY = this.makeNumericRangeQuery(field_maxY, null, bbox.getMaxY(), false, true);
Query yConditions = this.makeQuery(BooleanClause.Occur.MUST, qMinY, qMaxY);
// X conditions
@@ -493,8 +571,8 @@ public class BBoxStrategy extends SpatialStrategy {
// queries that do not cross the date line
// docMinX >= queryExtent.getMinX() AND docMaxX <= queryExtent.getMaxX()
- Query qMinX = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
- Query qMaxX = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+ Query qMinX = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
+ Query qMaxX = this.makeNumericRangeQuery(field_maxX, null, bbox.getMaxX(), false, true);
Query qMinMax = this.makeQuery(BooleanClause.Occur.MUST, qMinX, qMaxX);
double edge = 0;//none, otherwise opposite dateline of query
@@ -517,14 +595,14 @@ public class BBoxStrategy extends SpatialStrategy {
// the document should be within the left portion of the query
// docMinX >= queryExtent.getMinX() AND docMaxX <= 180.0
- Query qMinXLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
- Query qMaxXLeft = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, 180.0, false, true);
+ Query qMinXLeft = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
+ Query qMaxXLeft = this.makeNumericRangeQuery(field_maxX, null, 180.0, false, true);
Query qLeft = this.makeQuery(BooleanClause.Occur.MUST, qMinXLeft, qMaxXLeft);
// the document should be within the right portion of the query
// docMinX >= -180.0 AND docMaxX <= queryExtent.getMaxX()
- Query qMinXRight = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), -180.0, null, true, false);
- Query qMaxXRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+ Query qMinXRight = this.makeNumericRangeQuery(field_minX, -180.0, null, true, false);
+ Query qMaxXRight = this.makeNumericRangeQuery(field_maxX, null, bbox.getMaxX(), false, true);
Query qRight = this.makeQuery(BooleanClause.Occur.MUST, qMinXRight, qMaxXRight);
// either left or right conditions should occur,
@@ -537,8 +615,8 @@ public class BBoxStrategy extends SpatialStrategy {
// AND the right portion of the document must be within the right portion of the query
// docMinXLeft >= queryExtent.getMinX() AND docMaxXLeft <= 180.0
// AND docMinXRight >= -180.0 AND docMaxXRight <= queryExtent.getMaxX()
- Query qXDLLeft = LegacyNumericRangeQuery.newDoubleRange(field_minX, getPrecisionStep(), bbox.getMinX(), null, true, false);
- Query qXDLRight = LegacyNumericRangeQuery.newDoubleRange(field_maxX, getPrecisionStep(), null, bbox.getMaxX(), false, true);
+ Query qXDLLeft = this.makeNumericRangeQuery(field_minX, bbox.getMinX(), null, true, false);
+ Query qXDLRight = this.makeNumericRangeQuery(field_maxX, null, bbox.getMaxX(), false, true);
Query qXDLLeftRight = this.makeQuery(BooleanClause.Occur.MUST, qXDLLeft, qXDLRight);
Query qXDL = this.makeXDL(true, qXDLLeftRight);
@@ -581,9 +659,49 @@ public class BBoxStrategy extends SpatialStrategy {
}
private Query makeNumberTermQuery(String field, double number) {
- BytesRefBuilder bytes = new BytesRefBuilder();
- LegacyNumericUtils.longToPrefixCoded(NumericUtils.doubleToSortableLong(number), 0, bytes);
- return new TermQuery(new Term(field, bytes.get()));
+ if (hasPointVals) {
+ return DoublePoint.newExactQuery(field, number);
+ } else if (legacyNumericFieldType != null) {
+ BytesRefBuilder bytes = new BytesRefBuilder();
+ LegacyNumericUtils.longToPrefixCoded(NumericUtils.doubleToSortableLong(number), 0, bytes);
+ return new TermQuery(new Term(field, bytes.get()));
+ }
+ throw new UnsupportedOperationException("An index is required for this operation.");
}
+ /**
+ * Returns a numeric range query based on FieldType
+ * {@link LegacyNumericRangeQuery} is used for indexes created using {@code FieldType.LegacyNumericType}
+ * {@link DoublePoint#newRangeQuery} is used for indexes created using {@link DoublePoint} fields
+ *
+ * @param fieldname field name. must not be <code>null</code>.
+ * @param min minimum value of the range.
+ * @param max maximum value of the range.
+ * @param minInclusive include the minimum value if <code>true</code>.
+ * @param maxInclusive include the maximum value if <code>true</code>
+ */
+ private Query makeNumericRangeQuery(String fieldname, Double min, Double max, boolean minInclusive, boolean maxInclusive) {
+ if (hasPointVals) {
+ if (min == null) {
+ min = Double.NEGATIVE_INFINITY;
+ }
+
+ if (max == null) {
+ max = Double.POSITIVE_INFINITY;
+ }
+
+ if (minInclusive == false) {
+ min = Math.nextUp(min);
+ }
+
+ if (maxInclusive == false) {
+ max = Math.nextDown(max);
+ }
+
+ return DoublePoint.newRangeQuery(fieldname, min, max);
+ } else if (legacyNumericFieldType != null) {// todo remove legacy numeric support in 7.0
+ return LegacyNumericRangeQuery.newDoubleRange(fieldname, legacyNumericFieldType.numericPrecisionStep(), min, max, minInclusive, maxInclusive);
+ }
+ throw new UnsupportedOperationException("An index is required for this operation.");
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
index f5f5f34..197547c 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
@@ -16,14 +16,14 @@
*/
package org.apache.lucene.spatial.vector;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Circle;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Rectangle;
-import org.locationtech.spatial4j.shape.Shape;
-import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.DoubleDocValuesField;
+import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.LegacyDoubleField;
+import org.apache.lucene.document.StoredField;
+import org.apache.lucene.index.DocValuesType;
+import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.queries.function.FunctionRangeQuery;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.BooleanClause;
@@ -35,10 +35,15 @@ import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Circle;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Rectangle;
+import org.locationtech.spatial4j.shape.Shape;
/**
- * Simple {@link SpatialStrategy} which represents Points in two numeric {@link
- * org.apache.lucene.document.LegacyDoubleField}s. The Strategy's best feature is decent distance sort.
+ * Simple {@link SpatialStrategy} which represents Points in two numeric fields.
+ * The Strategy's best feature is decent distance sort.
*
* <p>
* <b>Characteristics:</b>
@@ -49,7 +54,7 @@ import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
* <li>{@link
* org.apache.lucene.spatial.query.SpatialOperation#Intersects} and {@link
* SpatialOperation#IsWithin} is supported.</li>
- * <li>Uses the FieldCache for
+ * <li>Requires DocValues for
* {@link #makeDistanceValueSource(org.locationtech.spatial4j.shape.Point)} and for
* searching with a Circle.</li>
* </ul>
@@ -57,8 +62,8 @@ import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
* <p>
* <b>Implementation:</b>
* <p>
- * This is a simple Strategy. Search works with {@link org.apache.lucene.search.LegacyNumericRangeQuery}s on
- * an x and y pair of fields. A Circle query does the same bbox query but adds a
+ * This is a simple Strategy. Search works with a pair of range queries on two {@link DoublePoint}s representing
+ * x & y fields. A Circle query does the same bbox query but adds a
* ValueSource filter on
* {@link #makeDistanceValueSource(org.locationtech.spatial4j.shape.Point)}.
* <p>
@@ -71,26 +76,105 @@ import org.apache.lucene.spatial.query.UnsupportedSpatialOperation;
*/
public class PointVectorStrategy extends SpatialStrategy {
+ // note: we use a FieldType to articulate the options we want on the field. We don't use it as-is with a Field, we
+ // create more than one Field.
+
+ /**
+ * pointValues, docValues, and nothing else.
+ */
+ public static FieldType DEFAULT_FIELDTYPE;
+
+ @Deprecated
+ public static FieldType LEGACY_FIELDTYPE;
+ static {
+ // Default: pointValues + docValues
+ FieldType type = new FieldType();
+ type.setDimensions(1, Double.BYTES);//pointValues (assume Double)
+ type.setDocValuesType(DocValuesType.NUMERIC);//docValues
+ type.setStored(false);
+ type.freeze();
+ DEFAULT_FIELDTYPE = type;
+ // Legacy default: legacyNumerics
+ type = new FieldType();
+ type.setIndexOptions(IndexOptions.DOCS);
+ type.setNumericType(FieldType.LegacyNumericType.DOUBLE);
+ type.setNumericPrecisionStep(8);// same as solr default
+ type.setDocValuesType(DocValuesType.NONE);//no docValues!
+ type.setStored(false);
+ type.freeze();
+ LEGACY_FIELDTYPE = type;
+ }
+
public static final String SUFFIX_X = "__x";
public static final String SUFFIX_Y = "__y";
private final String fieldNameX;
private final String fieldNameY;
- public int precisionStep = 8; // same as solr default
+ private final int fieldsLen;
+ private final boolean hasStored;
+ private final boolean hasDocVals;
+ private final boolean hasPointVals;
+ // equiv to "hasLegacyNumerics":
+ private final FieldType legacyNumericFieldType; // not stored; holds precision step.
+
+ /**
+ * Create a new {@link PointVectorStrategy} instance that uses {@link DoublePoint} and {@link DoublePoint#newRangeQuery}
+ */
+ public static PointVectorStrategy newInstance(SpatialContext ctx, String fieldNamePrefix) {
+ return new PointVectorStrategy(ctx, fieldNamePrefix, DEFAULT_FIELDTYPE);
+ }
+
+ /**
+ * Create a new {@link PointVectorStrategy} instance that uses {@link LegacyDoubleField} for backwards compatibility.
+ * However, back-compat is limited; we don't support circle queries or {@link #makeDistanceValueSource(Point, double)}
+ * since that requires docValues (the legacy config didn't have that).
+ *
+ * @deprecated LegacyNumerics will be removed
+ */
+ @Deprecated
+ public static PointVectorStrategy newLegacyInstance(SpatialContext ctx, String fieldNamePrefix) {
+ return new PointVectorStrategy(ctx, fieldNamePrefix, LEGACY_FIELDTYPE);
+ }
- public PointVectorStrategy(SpatialContext ctx, String fieldNamePrefix) {
+ /**
+ * Create a new instance configured with the provided FieldType options. See {@link #DEFAULT_FIELDTYPE}.
+ * a field type is used to articulate the desired options (namely pointValues, docValues, stored). Legacy numerics
+ * is configurable this way too.
+ */
+ public PointVectorStrategy(SpatialContext ctx, String fieldNamePrefix, FieldType fieldType) {
super(ctx, fieldNamePrefix);
this.fieldNameX = fieldNamePrefix+SUFFIX_X;
this.fieldNameY = fieldNamePrefix+SUFFIX_Y;
- }
- public void setPrecisionStep( int p ) {
- precisionStep = p;
- if (precisionStep<=0 || precisionStep>=64)
- precisionStep=Integer.MAX_VALUE;
+ int numPairs = 0;
+ if ((this.hasStored = fieldType.stored())) {
+ numPairs++;
+ }
+ if ((this.hasDocVals = fieldType.docValuesType() != DocValuesType.NONE)) {
+ numPairs++;
+ }
+ if ((this.hasPointVals = fieldType.pointDimensionCount() > 0)) {
+ numPairs++;
+ }
+ if (fieldType.indexOptions() != IndexOptions.NONE && fieldType.numericType() != null) {
+ if (hasPointVals) {
+ throw new IllegalArgumentException("pointValues and LegacyNumericType are mutually exclusive");
+ }
+ if (fieldType.numericType() != FieldType.LegacyNumericType.DOUBLE) {
+ throw new IllegalArgumentException(getClass() + " does not support " + fieldType.numericType());
+ }
+ numPairs++;
+ legacyNumericFieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
+ legacyNumericFieldType.setNumericPrecisionStep(fieldType.numericPrecisionStep());
+ legacyNumericFieldType.freeze();
+ } else {
+ legacyNumericFieldType = null;
+ }
+ this.fieldsLen = numPairs * 2;
}
+
String getFieldNameX() {
return fieldNameX;
}
@@ -108,12 +192,26 @@ public class PointVectorStrategy extends SpatialStrategy {
/** @see #createIndexableFields(org.locationtech.spatial4j.shape.Shape) */
public Field[] createIndexableFields(Point point) {
- FieldType doubleFieldType = new FieldType(LegacyDoubleField.TYPE_NOT_STORED);
- doubleFieldType.setNumericPrecisionStep(precisionStep);
- Field[] f = new Field[2];
- f[0] = new LegacyDoubleField(fieldNameX, point.getX(), doubleFieldType);
- f[1] = new LegacyDoubleField(fieldNameY, point.getY(), doubleFieldType);
- return f;
+ Field[] fields = new Field[fieldsLen];
+ int idx = -1;
+ if (hasStored) {
+ fields[++idx] = new StoredField(fieldNameX, point.getX());
+ fields[++idx] = new StoredField(fieldNameY, point.getY());
+ }
+ if (hasDocVals) {
+ fields[++idx] = new DoubleDocValuesField(fieldNameX, point.getX());
+ fields[++idx] = new DoubleDocValuesField(fieldNameY, point.getY());
+ }
+ if (hasPointVals) {
+ fields[++idx] = new DoublePoint(fieldNameX, point.getX());
+ fields[++idx] = new DoublePoint(fieldNameY, point.getY());
+ }
+ if (legacyNumericFieldType != null) {
+ fields[++idx] = new LegacyDoubleField(fieldNameX, point.getX(), legacyNumericFieldType);
+ fields[++idx] = new LegacyDoubleField(fieldNameY, point.getY(), legacyNumericFieldType);
+ }
+ assert idx == fields.length - 1;
+ return fields;
}
@Override
@@ -165,14 +263,27 @@ public class PointVectorStrategy extends SpatialStrategy {
return bq.build();
}
- private LegacyNumericRangeQuery<Double> rangeQuery(String fieldName, Double min, Double max) {
- return LegacyNumericRangeQuery.newDoubleRange(
- fieldName,
- precisionStep,
- min,
- max,
- true,
- true);//inclusive
- }
+ /**
+ * Returns a numeric range query based on FieldType
+ * {@link LegacyNumericRangeQuery} is used for indexes created using {@code FieldType.LegacyNumericType}
+ * {@link DoublePoint#newRangeQuery} is used for indexes created using {@link DoublePoint} fields
+ */
+ private Query rangeQuery(String fieldName, Double min, Double max) {
+ if (hasPointVals) {
+ if (min == null) {
+ min = Double.NEGATIVE_INFINITY;
+ }
+
+ if (max == null) {
+ max = Double.POSITIVE_INFINITY;
+ }
+
+ return DoublePoint.newRangeQuery(fieldName, min, max);
+ } else if (legacyNumericFieldType != null) {// todo remove legacy numeric support in 7.0
+ return LegacyNumericRangeQuery.newDoubleRange(fieldName, legacyNumericFieldType.numericPrecisionStep(), min, max, true, true);//inclusive
+ }
+ //TODO try doc-value range query?
+ throw new UnsupportedOperationException("An index is required for this operation.");
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
index 1602679..d54e1c9 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/DistanceStrategyTest.java
@@ -22,11 +22,6 @@ import java.util.Arrays;
import java.util.List;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Shape;
-import org.apache.lucene.document.FieldType;
-import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.spatial.bbox.BBoxStrategy;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
@@ -37,6 +32,9 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
import org.apache.lucene.spatial.vector.PointVectorStrategy;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Shape;
public class DistanceStrategyTest extends StrategyTestCase {
@ParametersFactory(argumentFormatting = "strategy=%s")
@@ -59,10 +57,18 @@ public class DistanceStrategyTest extends StrategyTestCase {
strategy = new RecursivePrefixTreeStrategy(grid, "recursive_packedquad");
ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
- strategy = new PointVectorStrategy(ctx, "pointvector");
+ strategy = PointVectorStrategy.newInstance(ctx, "pointvector");
+ ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+// Can't test this without un-inverting since PVS legacy config didn't have docValues.
+// However, note that Solr's tests use UninvertingReader and thus test this.
+// strategy = PointVectorStrategy.newLegacyInstance(ctx, "pointvector_legacy");
+// ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+ strategy = BBoxStrategy.newInstance(ctx, "bbox");
ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
- strategy = new BBoxStrategy(ctx, "bbox");
+ strategy = BBoxStrategy.newLegacyInstance(ctx, "bbox_legacy");
ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
strategy = new SerializedDVStrategy(ctx, "serialized");
@@ -76,22 +82,6 @@ public class DistanceStrategyTest extends StrategyTestCase {
this.strategy = strategy;
}
- @Override
- public void setUp() throws Exception {
- super.setUp();
- if (strategy instanceof BBoxStrategy && random().nextBoolean()) {//disable indexing sometimes
- BBoxStrategy bboxStrategy = (BBoxStrategy)strategy;
- final FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
- fieldType.setIndexOptions(IndexOptions.NONE);
- bboxStrategy.setFieldType(fieldType);
- }
- }
-
- @Override
- protected boolean needsDocValues() {
- return true;
- }
-
@Test
public void testDistanceOrder() throws IOException {
adoc("100", ctx.makePoint(2, 1));
@@ -108,9 +98,9 @@ public class DistanceStrategyTest extends StrategyTestCase {
@Test
public void testRecipScore() throws IOException {
- Point p100 = ctx.makePoint(2, 1);
+ Point p100 = ctx.makePoint(2.02, 0.98);
adoc("100", p100);
- Point p101 = ctx.makePoint(-1, 4);
+ Point p101 = ctx.makePoint(-1.001, 4.001);
adoc("101", p101);
adoc("103", (Shape)null);//test score for nothing
adoc("999", ctx.makePoint(2, 1));//test deleted
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
index a081497..f55daf6 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
@@ -22,10 +22,6 @@ import java.util.List;
import java.util.Set;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.distance.DistanceUtils;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Shape;
import org.apache.lucene.search.Query;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
@@ -36,6 +32,10 @@ import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.vector.PointVectorStrategy;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.distance.DistanceUtils;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Shape;
/**
* Based off of Solr 3's SpatialFilterTest.
@@ -62,7 +62,10 @@ public class PortedSolr3Test extends StrategyTestCase {
strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
- strategy = new PointVectorStrategy(ctx, "pointvector");
+ strategy = PointVectorStrategy.newInstance(ctx, "pointvector");
+ ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
+
+ strategy = PointVectorStrategy.newInstance(ctx, "pointvector_legacy");
ctorArgs.add(new Object[]{strategy.getFieldName(), strategy});
return ctorArgs;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
index 5dbb8f8..c14fe54 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/QueryEqualsHashCodeTest.java
@@ -19,8 +19,6 @@ package org.apache.lucene.spatial;
import java.util.ArrayList;
import java.util.Collection;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Shape;
import org.apache.lucene.spatial.bbox.BBoxStrategy;
import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
@@ -34,6 +32,8 @@ import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
import org.apache.lucene.spatial.vector.PointVectorStrategy;
import org.apache.lucene.util.LuceneTestCase;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Shape;
public class QueryEqualsHashCodeTest extends LuceneTestCase {
@@ -57,8 +57,10 @@ public class QueryEqualsHashCodeTest extends LuceneTestCase {
RecursivePrefixTreeStrategy recursive_geohash = new RecursivePrefixTreeStrategy(gridGeohash, "recursive_geohash");
strategies.add(recursive_geohash);
strategies.add(new TermQueryPrefixTreeStrategy(gridQuad, "termquery_quad"));
- strategies.add(new PointVectorStrategy(ctx, "pointvector"));
- strategies.add(new BBoxStrategy(ctx, "bbox"));
+ strategies.add(PointVectorStrategy.newInstance(ctx, "pointvector"));
+ strategies.add(PointVectorStrategy.newLegacyInstance(ctx, "pointvector_legacy"));
+ strategies.add(BBoxStrategy.newInstance(ctx, "bbox"));
+ strategies.add(BBoxStrategy.newLegacyInstance(ctx, "bbox_legacy"));
final SerializedDVStrategy serialized = new SerializedDVStrategy(ctx, "serialized");
strategies.add(serialized);
strategies.add(new CompositeSpatialStrategy("composite", recursive_geohash, serialized));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
index 8ccb9af..9f4ba02 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/SpatialTestCase.java
@@ -18,34 +18,26 @@ package org.apache.lucene.spatial;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Random;
import java.util.logging.Logger;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.distance.DistanceUtils;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Rectangle;
-
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
-import org.apache.lucene.uninverting.UninvertingReader;
-import org.apache.lucene.uninverting.UninvertingReader.Type;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
-import org.apache.lucene.util.TestUtil;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.distance.DistanceUtils;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Rectangle;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomGaussian;
@@ -66,36 +58,16 @@ public abstract class SpatialTestCase extends LuceneTestCase {
protected SpatialContext ctx;//subclass must initialize
- protected Map<String,Type> uninvertMap = new HashMap<>();
-
@Override
public void setUp() throws Exception {
super.setUp();
- // TODO: change this module to index docvalues instead of uninverting
- uninvertMap.clear();
- uninvertMap.put("pointvector__x", Type.LEGACY_DOUBLE);
- uninvertMap.put("pointvector__y", Type.LEGACY_DOUBLE);
-
directory = newDirectory();
- final Random random = random();
- analyzer = new MockAnalyzer(random);
- indexWriter = new RandomIndexWriter(random,directory, newIWConfig(random, analyzer));
- indexReader = UninvertingReader.wrap(indexWriter.getReader(), uninvertMap);
+ analyzer = new MockAnalyzer(random());
+ indexWriter = new RandomIndexWriter(random(), directory, LuceneTestCase.newIndexWriterConfig(random(), analyzer));
+ indexReader = indexWriter.getReader();
indexSearcher = newSearcher(indexReader);
}
- protected IndexWriterConfig newIWConfig(Random random, Analyzer analyzer) {
- final IndexWriterConfig indexWriterConfig = LuceneTestCase.newIndexWriterConfig(random, analyzer);
- //TODO can we randomly choose a doc-values supported format?
- if (needsDocValues())
- indexWriterConfig.setCodec( TestUtil.getDefaultCodec());
- return indexWriterConfig;
- }
-
- protected boolean needsDocValues() {
- return false;
- }
-
@Override
public void tearDown() throws Exception {
IOUtils.close(indexWriter, indexReader, analyzer, directory);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
index 20a7202..01e9259 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/bbox/TestBBoxStrategy.java
@@ -19,12 +19,6 @@ package org.apache.lucene.spatial.bbox;
import java.io.IOException;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.context.SpatialContextFactory;
-import org.locationtech.spatial4j.distance.DistanceUtils;
-import org.locationtech.spatial4j.shape.Rectangle;
-import org.locationtech.spatial4j.shape.Shape;
-import org.locationtech.spatial4j.shape.impl.RectangleImpl;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.index.IndexOptions;
@@ -36,15 +30,16 @@ import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.util.ShapeAreaValueSource;
import org.junit.Ignore;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.context.SpatialContextFactory;
+import org.locationtech.spatial4j.distance.DistanceUtils;
+import org.locationtech.spatial4j.shape.Rectangle;
+import org.locationtech.spatial4j.shape.Shape;
+import org.locationtech.spatial4j.shape.impl.RectangleImpl;
public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
@Override
- protected boolean needsDocValues() {
- return true;
- }
-
- @Override
protected Shape randomIndexedShape() {
Rectangle world = ctx.getWorldBounds();
if (random().nextInt(10) == 0) // increased chance of getting one of these
@@ -97,13 +92,17 @@ public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
factory.worldBounds = new RectangleImpl(-300, 300, -100, 100, null);
this.ctx = factory.newSpatialContext();
}
- this.strategy = new BBoxStrategy(ctx, "bbox");
+ // randomly test legacy (numeric) and point based bbox strategy
+ if (random().nextBoolean()) {
+ this.strategy = BBoxStrategy.newInstance(ctx, "bbox");
+ } else {
+ this.strategy = BBoxStrategy.newLegacyInstance(ctx, "bbox");
+ }
//test we can disable docValues for predicate tests
if (random().nextBoolean()) {
- BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
- FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
+ FieldType fieldType = new FieldType(((BBoxStrategy)strategy).getFieldType());
fieldType.setDocValuesType(DocValuesType.NONE);
- bboxStrategy.setFieldType(fieldType);
+ strategy = new BBoxStrategy(ctx, strategy.getFieldName(), fieldType);
}
for (SpatialOperation operation : SpatialOperation.values()) {
if (operation == SpatialOperation.Overlaps)
@@ -189,7 +188,11 @@ public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
private void setupGeo() {
this.ctx = SpatialContext.GEO;
- this.strategy = new BBoxStrategy(ctx, "bbox");
+ if (random().nextBoolean()) {
+ this.strategy = BBoxStrategy.newInstance(ctx, "bbox");
+ } else {
+ this.strategy = BBoxStrategy.newLegacyInstance(ctx, "bbox");
+ }
}
// OLD STATIC TESTS (worthless?)
@@ -225,8 +228,29 @@ public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
return shape.getBoundingBox();
}
+ private BBoxStrategy setupNeedsDocValuesOnly() throws IOException {
+ this.ctx = SpatialContext.GEO;
+ FieldType fieldType;
+ // random legacy or not legacy
+ String FIELD_PREFIX = "bbox";
+ if (random().nextBoolean()) {
+ fieldType = new FieldType(BBoxStrategy.DEFAULT_FIELDTYPE);
+ if (random().nextBoolean()) {
+ fieldType.setDimensions(0, 0);
+ }
+ } else {
+ fieldType = new FieldType(BBoxStrategy.LEGACY_FIELDTYPE);
+ if (random().nextBoolean()) {
+ fieldType.setIndexOptions(IndexOptions.NONE);
+ }
+ }
+
+ strategy = new BBoxStrategy(ctx, FIELD_PREFIX, fieldType);
+ return (BBoxStrategy)strategy;
+ }
+
public void testOverlapRatio() throws IOException {
- setupGeo();
+ setupNeedsDocValuesOnly();
//Simply assert null shape results in 0
adoc("999", (Shape) null);
@@ -279,14 +303,7 @@ public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
}
public void testAreaValueSource() throws IOException {
- setupGeo();
- //test we can disable indexed for this test
- BBoxStrategy bboxStrategy = (BBoxStrategy) strategy;
- if (random().nextBoolean()) {
- FieldType fieldType = new FieldType(bboxStrategy.getFieldType());
- fieldType.setIndexOptions(IndexOptions.NONE);
- bboxStrategy.setFieldType(fieldType);
- }
+ BBoxStrategy bboxStrategy = setupNeedsDocValuesOnly();
adoc("100", ctx.makeRectangle(0, 20, 40, 80));
adoc("999", (Shape) null);
@@ -298,4 +315,5 @@ public class TestBBoxStrategy extends RandomSpatialOpStrategyTestCase {
checkValueSource(new ShapeAreaValueSource(bboxStrategy.makeShapeValueSource(), ctx, true, 2.0),
new float[]{783.86f, 0f}, 0.01f); // testing with a different multiplier
}
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
index 7d49e8b..e74c2b5 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/composite/CompositeStrategyTest.java
@@ -19,12 +19,6 @@ package org.apache.lucene.spatial.composite;
import java.io.IOException;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.context.SpatialContextFactory;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Rectangle;
-import org.locationtech.spatial4j.shape.Shape;
-import org.locationtech.spatial4j.shape.impl.RectangleImpl;
import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
@@ -33,6 +27,12 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.context.SpatialContextFactory;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Rectangle;
+import org.locationtech.spatial4j.shape.Shape;
+import org.locationtech.spatial4j.shape.impl.RectangleImpl;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomDouble;
@@ -102,11 +102,6 @@ public class CompositeStrategyTest extends RandomSpatialOpStrategyTestCase {
}
@Override
- protected boolean needsDocValues() {
- return true;//due to SerializedDVStrategy
- }
-
- @Override
protected Shape randomIndexedShape() {
return randomShape();
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
index 6a73d23..8466ae1 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/serialized/SerializedStrategyTest.java
@@ -18,11 +18,11 @@ package org.apache.lucene.spatial.serialized;
import java.io.IOException;
-import org.locationtech.spatial4j.context.SpatialContext;
import org.apache.lucene.spatial.SpatialMatchConcern;
import org.apache.lucene.spatial.StrategyTestCase;
import org.junit.Before;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
public class SerializedStrategyTest extends StrategyTestCase {
@@ -34,11 +34,6 @@ public class SerializedStrategyTest extends StrategyTestCase {
this.strategy = new SerializedDVStrategy(ctx, "serialized");
}
- @Override
- protected boolean needsDocValues() {
- return (strategy instanceof SerializedDVStrategy);
- }
-
@Test
public void testBasicOperaions() throws IOException {
getAddAndVerifyIndexedDocuments(DATA_SIMPLE_BBOX);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
index e62b857..2bef2b7 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/spatial4j/Geo3dRptTest.java
@@ -21,10 +21,6 @@ import java.util.ArrayList;
import java.util.List;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Point;
-import org.locationtech.spatial4j.shape.Rectangle;
-import org.locationtech.spatial4j.shape.Shape;
import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
import org.apache.lucene.spatial.prefix.RandomSpatialOpStrategyTestCase;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
@@ -33,13 +29,17 @@ import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
import org.apache.lucene.spatial3d.geom.GeoBBoxFactory;
-import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
import org.apache.lucene.spatial3d.geom.GeoPath;
import org.apache.lucene.spatial3d.geom.GeoPoint;
import org.apache.lucene.spatial3d.geom.GeoPolygonFactory;
import org.apache.lucene.spatial3d.geom.GeoShape;
+import org.apache.lucene.spatial3d.geom.GeoStandardCircle;
import org.apache.lucene.spatial3d.geom.PlanetModel;
import org.junit.Test;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Point;
+import org.locationtech.spatial4j.shape.Rectangle;
+import org.locationtech.spatial4j.shape.Shape;
import static org.locationtech.spatial4j.distance.DistanceUtils.DEGREES_TO_RADIANS;
@@ -63,11 +63,6 @@ public class Geo3dRptTest extends RandomSpatialOpStrategyTestCase {
return rpt;
}
- @Override
- protected boolean needsDocValues() {
- return true;//due to SerializedDVStrategy
- }
-
private void setupStrategy() {
//setup
setupGeohashGrid();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
----------------------------------------------------------------------
diff --git a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
index 69f8c4d..ac5ab95 100644
--- a/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
+++ b/lucene/spatial-extras/src/test/org/apache/lucene/spatial/vector/TestPointVectorStrategy.java
@@ -16,9 +16,12 @@
*/
package org.apache.lucene.spatial.vector;
-import org.locationtech.spatial4j.context.SpatialContext;
-import org.locationtech.spatial4j.shape.Circle;
-import org.locationtech.spatial4j.shape.Point;
+import java.io.IOException;
+import java.text.ParseException;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.spatial.SpatialMatchConcern;
import org.apache.lucene.spatial.StrategyTestCase;
@@ -26,8 +29,9 @@ import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.junit.Before;
import org.junit.Test;
-
-import java.io.IOException;
+import org.locationtech.spatial4j.context.SpatialContext;
+import org.locationtech.spatial4j.shape.Circle;
+import org.locationtech.spatial4j.shape.Point;
public class TestPointVectorStrategy extends StrategyTestCase {
@@ -36,11 +40,11 @@ public class TestPointVectorStrategy extends StrategyTestCase {
public void setUp() throws Exception {
super.setUp();
this.ctx = SpatialContext.GEO;
- this.strategy = new PointVectorStrategy(ctx, getClass().getSimpleName());
}
@Test
public void testCircleShapeSupport() {
+ this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName());
Circle circle = ctx.makeCircle(ctx.makePoint(0, 0), 10);
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle);
Query query = this.strategy.makeQuery(args);
@@ -50,6 +54,7 @@ public class TestPointVectorStrategy extends StrategyTestCase {
@Test(expected = UnsupportedOperationException.class)
public void testInvalidQueryShape() {
+ this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName());
Point point = ctx.makePoint(0, 0);
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point);
this.strategy.makeQuery(args);
@@ -57,7 +62,45 @@ public class TestPointVectorStrategy extends StrategyTestCase {
@Test
public void testCitiesIntersectsBBox() throws IOException {
+ // note: does not require docValues
+ if (random().nextBoolean()) {
+ this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName());
+ } else {
+ // switch to legacy instance sometimes, which has no docValues
+ this.strategy = PointVectorStrategy.newLegacyInstance(ctx, getClass().getSimpleName());
+ }
getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
}
+
+ @Test
+ public void testFieldOptions() throws IOException, ParseException {
+ // It's not stored; test it isn't.
+ this.strategy = PointVectorStrategy.newInstance(ctx, getClass().getSimpleName());
+ adoc("99", "POINT(-5.0 8.2)");
+ commit();
+ SearchResults results = executeQuery(new MatchAllDocsQuery(), 1);
+ Document document = results.results.get(0).document;
+ assertNull("not stored", document.getField(strategy.getFieldName() + PointVectorStrategy.SUFFIX_X));
+ assertNull("not stored", document.getField(strategy.getFieldName() + PointVectorStrategy.SUFFIX_Y));
+ deleteAll();
+
+ // Now we mark it stored. We also disable pointvalues...
+ FieldType fieldType = new FieldType(PointVectorStrategy.DEFAULT_FIELDTYPE);
+ fieldType.setStored(true);
+ fieldType.setDimensions(0, 0);//disable point values
+ this.strategy = new PointVectorStrategy(ctx, getClass().getSimpleName(), fieldType);
+ adoc("99", "POINT(-5.0 8.2)");
+ commit();
+ results = executeQuery(new MatchAllDocsQuery(), 1);
+ document = results.results.get(0).document;
+ assertEquals("stored", -5.0, document.getField(strategy.getFieldName() + PointVectorStrategy.SUFFIX_X).numericValue());
+ assertEquals("stored", 8.2, document.getField(strategy.getFieldName() + PointVectorStrategy.SUFFIX_Y).numericValue());
+
+ // Test a query fails without point values
+ expectThrows(UnsupportedOperationException.class, () -> {
+ SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeRectangle(-10.0, 10.0, -5.0, 5.0));
+ this.strategy.makeQuery(args);
+ });
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/solr/core/src/java/org/apache/solr/schema/BBoxField.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/BBoxField.java b/solr/core/src/java/org/apache/solr/schema/BBoxField.java
index f655e68..e41d3c6 100644
--- a/solr/core/src/java/org/apache/solr/schema/BBoxField.java
+++ b/solr/core/src/java/org/apache/solr/schema/BBoxField.java
@@ -22,7 +22,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import org.locationtech.spatial4j.shape.Rectangle;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.spatial.bbox.BBoxOverlapRatioValueSource;
@@ -31,6 +30,7 @@ import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.util.ShapeAreaValueSource;
import org.apache.solr.common.SolrException;
import org.apache.solr.search.QParser;
+import org.locationtech.spatial4j.shape.Rectangle;
public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements SchemaAware {
private static final String PARAM_QUERY_TARGET_PROPORTION = "queryTargetProportion";
@@ -133,7 +133,6 @@ public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements
registerSubFields(schema, fieldName, numberType, booleanType);
}
- BBoxStrategy strategy = new BBoxStrategy(ctx, fieldName);
//Solr's FieldType ought to expose Lucene FieldType. Instead as a hack we create a Field with a dummy value.
final SchemaField solrNumField = new SchemaField("_", numberType);//dummy temp
org.apache.lucene.document.FieldType luceneType =
@@ -145,8 +144,7 @@ public class BBoxField extends AbstractSpatialFieldType<BBoxStrategy> implements
luceneType = new org.apache.lucene.document.FieldType(luceneType);
luceneType.setDocValuesType(DocValuesType.NUMERIC);
}
- strategy.setFieldType(luceneType);
- return strategy;
+ return new BBoxStrategy(ctx, fieldName, luceneType);
}
@Override
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f9da8164/solr/core/src/java/org/apache/solr/schema/SpatialPointVectorFieldType.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/SpatialPointVectorFieldType.java b/solr/core/src/java/org/apache/solr/schema/SpatialPointVectorFieldType.java
index 99bf3fe..18d80a3 100644
--- a/solr/core/src/java/org/apache/solr/schema/SpatialPointVectorFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/SpatialPointVectorFieldType.java
@@ -16,12 +16,12 @@
*/
package org.apache.solr.schema;
-import org.apache.lucene.spatial.vector.PointVectorStrategy;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import org.apache.lucene.spatial.vector.PointVectorStrategy;
+
/**
* @see PointVectorStrategy
* @lucene.experimental
@@ -78,10 +78,23 @@ public class SpatialPointVectorFieldType extends AbstractSpatialFieldType<PointV
}
@Override
+ public org.apache.lucene.document.FieldType.LegacyNumericType getNumericType() {
+ return org.apache.lucene.document.FieldType.LegacyNumericType.DOUBLE;
+ }
+
+ @Override
protected PointVectorStrategy newSpatialStrategy(String fieldName) {
- PointVectorStrategy strategy = new PointVectorStrategy(ctx, fieldName);
- strategy.setPrecisionStep(precisionStep);
- return strategy;
+ // TODO update to how BBoxField does things
+ if (this.getNumericType() != null) {
+ // create strategy based on legacy numerics
+ // todo remove in 7.0
+ org.apache.lucene.document.FieldType fieldType =
+ new org.apache.lucene.document.FieldType(PointVectorStrategy.LEGACY_FIELDTYPE);
+ fieldType.setNumericPrecisionStep(precisionStep);
+ return new PointVectorStrategy(ctx, fieldName, fieldType);
+ } else {
+ return PointVectorStrategy.newInstance(ctx, fieldName);
+ }
}
}