diff --git a/solr/core/src/java/org/apache/solr/schema/PointField.java b/solr/core/src/java/org/apache/solr/schema/PointField.java
index 1168386dca5..8746dac515f 100644
--- a/solr/core/src/java/org/apache/solr/schema/PointField.java
+++ b/solr/core/src/java/org/apache/solr/schema/PointField.java
@@ -28,6 +28,7 @@ import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortedNumericSelector;
import org.apache.lucene.util.BytesRef;
@@ -117,6 +118,10 @@ public abstract class PointField extends NumericFieldType {
if (!field.indexed() && field.hasDocValues()) {
// currently implemented as singleton range
return getRangeQuery(parser, field, externalVal, externalVal, true, true);
+ } else if (field.indexed() && field.hasDocValues()) {
+ Query pointsQuery = getExactQuery(field, externalVal);
+ Query dvQuery = getDocValuesRangeQuery(parser, field, externalVal, externalVal, true, true);
+ return new IndexOrDocValuesQuery(pointsQuery, dvQuery);
} else {
return getExactQuery(field, externalVal);
}
@@ -132,6 +137,10 @@ public abstract class PointField extends NumericFieldType {
boolean maxInclusive) {
if (!field.indexed() && field.hasDocValues()) {
return getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+ } else if (field.indexed() && field.hasDocValues()) {
+ Query pointsQuery = getPointRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+ Query dvQuery = getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
+ return new IndexOrDocValuesQuery(pointsQuery, dvQuery);
} else {
return getPointRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
}
diff --git a/solr/core/src/test-files/solr/collection1/conf/schema.xml b/solr/core/src/test-files/solr/collection1/conf/schema.xml
index ef7fc8df7bf..c53be9b537f 100644
--- a/solr/core/src/test-files/solr/collection1/conf/schema.xml
+++ b/solr/core/src/test-files/solr/collection1/conf/schema.xml
@@ -395,7 +395,7 @@
-
+
@@ -620,6 +620,7 @@
+
diff --git a/solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java b/solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java
index 56eb7e04d4f..f788ba0f721 100644
--- a/solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/PolyFieldTest.java
@@ -111,13 +111,17 @@ public class PolyFieldTest extends SolrTestCaseJ4 {
//
}
- //
+
SchemaField s1 = schema.getField("test_p");
SchemaField s2 = schema.getField("test_p");
- ValueSource v1 = s1.getType().getValueSource(s1, null);
- ValueSource v2 = s2.getType().getValueSource(s2, null);
- assertEquals(v1, v2);
- assertEquals(v1.hashCode(), v2.hashCode());
+ // If we use [Int/Double/Long/Float]PointField, we can't get the valueSource, since docValues is false
+ if (s1.createFields("1,2", 0).get(0).fieldType().pointDimensionCount() == 0) {
+ assertFalse(s2.getType().isPointField());
+ ValueSource v1 = s1.getType().getValueSource(s1, null);
+ ValueSource v2 = s2.getType().getValueSource(s2, null);
+ assertEquals(v1, v2);
+ assertEquals(v1.hashCode(), v2.hashCode());
+ }
}
@Test
diff --git a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
index bf34ce4f560..b3d0b97fa1d 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java
@@ -21,6 +21,8 @@ import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;
+import org.apache.lucene.search.IndexOrDocValuesQuery;
+import org.apache.lucene.search.PointRangeQuery;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrException;
import org.junit.After;
@@ -71,6 +73,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testIntPointFieldRangeQuery() throws Exception {
doTestIntPointFieldRangeQuery("number_p_i", "int", false);
doTestIntPointFieldRangeQuery("number_p_i_ni_ns_dv", "int", false);
+ doTestIntPointFieldRangeQuery("number_p_i_dv", "int", false);
}
@Test
@@ -120,6 +123,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testIntPointFieldMultiValuedRangeQuery() throws Exception {
testPointFieldMultiValuedRangeQuery("number_p_i_mv", "int", getSequentialStringArrayWithInts(20));
testPointFieldMultiValuedRangeQuery("number_p_i_ni_mv_dv", "int", getSequentialStringArrayWithInts(20));
+ testPointFieldMultiValuedRangeQuery("number_p_i_mv_dv", "int", getSequentialStringArrayWithInts(20));
}
//TODO MV SORT?
@@ -198,6 +202,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testDoublePointFieldRangeQuery() throws Exception {
doTestFloatPointFieldRangeQuery("number_p_d", "double", true);
doTestFloatPointFieldRangeQuery("number_p_d_ni_ns_dv", "double", true);
+ doTestFloatPointFieldRangeQuery("number_p_d_dv", "double", true);
}
@Test
@@ -249,6 +254,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testDoublePointFieldMultiValuedRangeQuery() throws Exception {
testPointFieldMultiValuedRangeQuery("number_p_d_mv", "double", getSequentialStringArrayWithDoubles(20));
testPointFieldMultiValuedRangeQuery("number_p_d_ni_mv_dv", "double", getSequentialStringArrayWithDoubles(20));
+ testPointFieldMultiValuedRangeQuery("number_p_d_mv_dv", "double", getSequentialStringArrayWithDoubles(20));
}
@Test
@@ -360,6 +366,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testFloatPointFieldRangeQuery() throws Exception {
doTestFloatPointFieldRangeQuery("number_p_f", "float", false);
doTestFloatPointFieldRangeQuery("number_p_f_ni_ns_dv", "float", false);
+ doTestFloatPointFieldRangeQuery("number_p_f_dv", "float", false);
}
@Test
@@ -411,6 +418,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testFloatPointFieldMultiValuedRangeQuery() throws Exception {
testPointFieldMultiValuedRangeQuery("number_p_f_mv", "float", getSequentialStringArrayWithDoubles(20));
testPointFieldMultiValuedRangeQuery("number_p_f_ni_mv_dv", "float", getSequentialStringArrayWithDoubles(20));
+ testPointFieldMultiValuedRangeQuery("number_p_f_mv_dv", "float", getSequentialStringArrayWithDoubles(20));
}
@Test
@@ -481,6 +489,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testLongPointFieldRangeQuery() throws Exception {
doTestIntPointFieldRangeQuery("number_p_l", "long", true);
doTestIntPointFieldRangeQuery("number_p_l_ni_ns_dv", "long", true);
+ doTestIntPointFieldRangeQuery("number_p_l_dv", "long", true);
}
@Test
@@ -533,6 +542,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
public void testLongPointFieldMultiValuedRangeQuery() throws Exception {
testPointFieldMultiValuedRangeQuery("number_p_l_mv", "long", getSequentialStringArrayWithInts(20));
testPointFieldMultiValuedRangeQuery("number_p_l_ni_mv_dv", "long", getSequentialStringArrayWithInts(20));
+ testPointFieldMultiValuedRangeQuery("number_p_l_mv_dv", "long", getSequentialStringArrayWithInts(20));
}
@Test
@@ -578,6 +588,27 @@ public class TestPointFields extends SolrTestCaseJ4 {
doTestSetQueries("number_p_l_ni_dv", getRandomStringArrayWithLongs(10, false), false);
}
+ @Test
+ public void testIndexOrDocValuesQuery() throws Exception {
+ String[] fieldTypeNames = new String[]{"_p_i", "_p_l", "_p_d", "_p_f"};
+ FieldType[] fieldTypes = new FieldType[]{new IntPointField(), new LongPointField(), new DoublePointField(), new FloatPointField()};
+ assert fieldTypeNames.length == fieldTypes.length;
+ for (int i = 0; i < fieldTypeNames.length; i++) {
+ SchemaField fieldIndexed = h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i]);
+ SchemaField fieldIndexedAndDv = h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_dv");
+ SchemaField fieldIndexedMv = h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_mv");
+ SchemaField fieldIndexedAndDvMv = h.getCore().getLatestSchema().getField("foo_" + fieldTypeNames[i] + "_mv_dv");
+ assertTrue(fieldTypes[i].getRangeQuery(null, fieldIndexed, "0", "10", true, true) instanceof PointRangeQuery);
+ assertTrue(fieldTypes[i].getRangeQuery(null, fieldIndexedAndDv, "0", "10", true, true) instanceof IndexOrDocValuesQuery);
+ assertTrue(fieldTypes[i].getRangeQuery(null, fieldIndexedMv, "0", "10", true, true) instanceof PointRangeQuery);
+ assertTrue(fieldTypes[i].getRangeQuery(null, fieldIndexedAndDvMv, "0", "10", true, true) instanceof IndexOrDocValuesQuery);
+ assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexed, "0") instanceof PointRangeQuery);
+ assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexedAndDv, "0") instanceof IndexOrDocValuesQuery);
+ assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexedMv, "0") instanceof PointRangeQuery);
+ assertTrue(fieldTypes[i].getFieldQuery(null, fieldIndexedAndDvMv, "0") instanceof IndexOrDocValuesQuery);
+ }
+ }
+
// Helper methods
private String[] getRandomStringArrayWithDoubles(int length, boolean sorted) {
@@ -803,14 +834,29 @@ public class TestPointFields extends SolrTestCaseJ4 {
"//result/doc[1]/" + type + "[@name='" + fieldName + "'][.='0']",
"//result/doc[10]/" + type + "[@name='" + fieldName + "'][.='9']");
+ assertQ(req("q", fieldName + ":[0 TO 1] OR " + fieldName + ":[8 TO 9]" , "fl", "id, " + fieldName),
+ "//*[@numFound='4']",
+ "//result/doc[1]/" + type + "[@name='" + fieldName + "'][.='0']",
+ "//result/doc[2]/" + type + "[@name='" + fieldName + "'][.='1']",
+ "//result/doc[3]/" + type + "[@name='" + fieldName + "'][.='8']",
+ "//result/doc[4]/" + type + "[@name='" + fieldName + "'][.='9']");
+
+ assertQ(req("q", fieldName + ":[0 TO 1] AND " + fieldName + ":[1 TO 2]" , "fl", "id, " + fieldName),
+ "//*[@numFound='1']",
+ "//result/doc[1]/" + type + "[@name='" + fieldName + "'][.='1']");
+
+ assertQ(req("q", fieldName + ":[0 TO 1] AND NOT " + fieldName + ":[1 TO 2]" , "fl", "id, " + fieldName),
+ "//*[@numFound='1']",
+ "//result/doc[1]/" + type + "[@name='" + fieldName + "'][.='0']");
+
clearIndex();
assertU(commit());
String[] arr;
if (testLong) {
- arr = getRandomStringArrayWithLongs(10, true);
+ arr = getRandomStringArrayWithLongs(100, true);
} else {
- arr = getRandomStringArrayWithInts(10, true);
+ arr = getRandomStringArrayWithInts(100, true);
}
for (int i = 0; i < arr.length; i++) {
assertU(adoc("id", String.valueOf(i), fieldName, arr[i]));
@@ -821,6 +867,8 @@ public class TestPointFields extends SolrTestCaseJ4 {
"//*[@numFound='" + (i + 1) + "']");
assertQ(req("q", fieldName + ":{" + arr[0] + " TO " + arr[i] + "}", "fl", "id, " + fieldName),
"//*[@numFound='" + (Math.max(0, i-1)) + "']");
+ assertQ(req("q", fieldName + ":[" + arr[0] + " TO " + arr[i] + "] AND " + fieldName + ":" + arr[0].replace("-", "\\-"), "fl", "id, " + fieldName),
+ "//*[@numFound='1']");
}
}
@@ -1092,6 +1140,17 @@ public class TestPointFields extends SolrTestCaseJ4 {
"//*[@numFound='10']",
"//result/doc[1]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[0] + "']",
"//result/doc[10]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[9] + "']");
+
+ assertQ(req("q", fieldName + ":[0 TO 1] OR " + fieldName + ":[8 TO 9]", "fl", "id, " + fieldName),
+ "//*[@numFound='4']",
+ "//result/doc[1]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[0] + "']",
+ "//result/doc[2]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[1] + "']",
+ "//result/doc[3]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[8] + "']",
+ "//result/doc[4]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[9] + "']");
+
+ assertQ(req("q", fieldName + ":[0 TO 0] AND " + fieldName + ":[10 TO 10]", "fl", "id, " + fieldName),
+ "//*[@numFound='1']",
+ "//result/doc[1]/arr[@name='" + fieldName + "']/" + type + "[1][.='" + numbers[0] + "']");
}
private void testPointFieldMultiValuedFacetField(String nonDocValuesField, String dvFieldName, String[] numbers) throws Exception {
diff --git a/solr/core/src/test/org/apache/solr/search/TestMaxScoreQueryParser.java b/solr/core/src/test/org/apache/solr/search/TestMaxScoreQueryParser.java
index 610e9982d4a..4699a6653c5 100644
--- a/solr/core/src/test/org/apache/solr/search/TestMaxScoreQueryParser.java
+++ b/solr/core/src/test/org/apache/solr/search/TestMaxScoreQueryParser.java
@@ -46,7 +46,8 @@ public class TestMaxScoreQueryParser extends AbstractSolrTestCase {
assertEquals(new BoostQuery(new TermQuery(new Term("text", "foo")), 3f), q);
q = parse("price:[0 TO 10]");
- assertTrue(q instanceof LegacyNumericRangeQuery || q instanceof PointRangeQuery);
+ assertTrue(q instanceof LegacyNumericRangeQuery
+ || (q instanceof IndexOrDocValuesQuery && ((IndexOrDocValuesQuery)q).getIndexQuery() instanceof PointRangeQuery));
}
@Test