SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType.

The TrieField.TrieTypes and PointField.PointTypes are now consolidated to NumericFieldType.NumberType. This
  refactoring also fixes a bug whereby PointFields were not using DocValues for range queries for
  indexed=false, docValues=true fields.
This commit is contained in:
Ishan Chattopadhyaya 2017-01-22 04:27:11 +05:30
parent 49fa7b0dd5
commit 285a1013ad
17 changed files with 239 additions and 194 deletions

View File

@ -80,6 +80,11 @@ Other Changes
----------------------
* SOLR-8396: Add support for PointFields in Solr (Ishan Chattopadhyaya, Tomás Fernández Löbbe)
* SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType. The
TrieField.TrieTypes and PointField.PointTypes are now consolidated to NumericFieldType.NumberType. This
refactoring also fixes a bug whereby PointFields were not using DocValues for range queries for
indexed=false, docValues=true fields.
================== 6.5.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.

View File

@ -45,6 +45,10 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public DoublePointField() {
type = NumberType.DOUBLE;
}
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
@ -54,7 +58,7 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
double actualMin, actualMax;
if (min == null) {
@ -179,9 +183,4 @@ public class DoublePointField extends PointField implements DoubleValueFieldType
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Double) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.DOUBLE;
}
}

View File

@ -45,6 +45,10 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public FloatPointField() {
type = NumberType.FLOAT;
}
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
@ -54,7 +58,7 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
float actualMin, actualMax;
if (min == null) {
@ -179,9 +183,4 @@ public class FloatPointField extends PointField implements FloatValueFieldType {
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Float) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.FLOAT;
}
}

View File

@ -44,6 +44,10 @@ public class IntPointField extends PointField implements IntValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public IntPointField() {
type = NumberType.INTEGER;
}
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
@ -58,7 +62,7 @@ public class IntPointField extends PointField implements IntValueFieldType {
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
int actualMin, actualMax;
if (min == null) {
@ -179,8 +183,4 @@ public class IntPointField extends PointField implements IntValueFieldType {
return new StoredField(sf.getName(), (Integer) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.INTEGER;
}
}

View File

@ -44,6 +44,10 @@ public class LongPointField extends PointField implements LongValueFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public LongPointField() {
type = NumberType.LONG;
}
@Override
public Object toNativeType(Object val) {
if (val == null) return null;
@ -58,7 +62,7 @@ public class LongPointField extends PointField implements LongValueFieldType {
}
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
public Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
long actualMin, actualMax;
if (min == null) {
@ -178,9 +182,4 @@ public class LongPointField extends PointField implements LongValueFieldType {
protected StoredField getStoredField(SchemaField sf, Object value) {
return new StoredField(sf.getName(), (Long) this.toNativeType(value));
}
@Override
public PointTypes getType() {
return PointTypes.LONG;
}
}

View File

@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.schema;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrException;
import org.apache.solr.search.FunctionRangeQuery;
import org.apache.solr.search.QParser;
import org.apache.solr.search.function.ValueSourceRangeFilter;
import org.apache.solr.util.DateMathParser;
public abstract class NumericFieldType extends PrimitiveFieldType {
public static enum NumberType {
INTEGER,
LONG,
FLOAT,
DOUBLE,
DATE
}
protected NumberType type;
/**
* @return the type of this field
*/
final public NumberType getType() {
return type;
}
private static long FLOAT_NEGATIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.NEGATIVE_INFINITY);
private static long DOUBLE_NEGATIVE_INFINITY_BITS = Double.doubleToLongBits(Double.NEGATIVE_INFINITY);
private static long FLOAT_POSITIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.POSITIVE_INFINITY);
private static long DOUBLE_POSITIVE_INFINITY_BITS = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
private static long FLOAT_MINUS_ZERO_BITS = (long)Float.floatToIntBits(-0f);
private static long DOUBLE_MINUS_ZERO_BITS = Double.doubleToLongBits(-0d);
private static long FLOAT_ZERO_BITS = (long)Float.floatToIntBits(0f);
private static long DOUBLE_ZERO_BITS = Double.doubleToLongBits(0d);
protected Query getDocValuesRangeQuery(QParser parser, SchemaField field, String min, String max,
boolean minInclusive, boolean maxInclusive) {
assert field.hasDocValues() && !field.multiValued();
switch (getType()) {
case INTEGER:
return numericDocValuesRangeQuery(field.getName(),
min == null ? null : (long) Integer.parseInt(min),
max == null ? null : (long) Integer.parseInt(max),
minInclusive, maxInclusive);
case FLOAT:
return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
case LONG:
return numericDocValuesRangeQuery(field.getName(),
min == null ? null : Long.parseLong(min),
max == null ? null : Long.parseLong(max),
minInclusive, maxInclusive);
case DOUBLE:
return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
case DATE:
return numericDocValuesRangeQuery(field.getName(),
min == null ? null : DateMathParser.parseMath(null, min).getTime(),
max == null ? null : DateMathParser.parseMath(null, max).getTime(),
minInclusive, maxInclusive);
default:
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for point field");
}
}
protected Query getRangeQueryForFloatDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
Query query;
String fieldName = sf.getName();
Number minVal = min == null ? null : getType() == NumberType.FLOAT ? Float.parseFloat(min): Double.parseDouble(min);
Number maxVal = max == null ? null : getType() == NumberType.FLOAT ? Float.parseFloat(max): Double.parseDouble(max);
Long minBits =
min == null ? null : getType() == NumberType.FLOAT ? (long) Float.floatToIntBits(minVal.floatValue()): Double.doubleToLongBits(minVal.doubleValue());
Long maxBits =
max == null ? null : getType() == NumberType.FLOAT ? (long) Float.floatToIntBits(maxVal.floatValue()): Double.doubleToLongBits(maxVal.doubleValue());
long negativeInfinityBits = getType() == NumberType.FLOAT ? FLOAT_NEGATIVE_INFINITY_BITS : DOUBLE_NEGATIVE_INFINITY_BITS;
long positiveInfinityBits = getType() == NumberType.FLOAT ? FLOAT_POSITIVE_INFINITY_BITS : DOUBLE_POSITIVE_INFINITY_BITS;
long minusZeroBits = getType() == NumberType.FLOAT ? FLOAT_MINUS_ZERO_BITS : DOUBLE_MINUS_ZERO_BITS;
long zeroBits = getType() == NumberType.FLOAT ? FLOAT_ZERO_BITS : DOUBLE_ZERO_BITS;
// If min is negative (or -0d) and max is positive (or +0d), then issue a FunctionRangeQuery
if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
(maxVal == null || (maxVal.doubleValue() > 0d || maxBits == zeroBits))) {
ValueSource vs = getValueSource(sf, null);
query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, min, max, minInclusive, maxInclusive));
} else { // If both max and min are negative (or -0d), then issue range query with max and min reversed
if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
(maxVal != null && (maxVal.doubleValue() < 0d || maxBits == minusZeroBits))) {
query = numericDocValuesRangeQuery
(fieldName, maxBits, (min == null ? negativeInfinityBits : minBits), maxInclusive, minInclusive);
} else { // If both max and min are positive, then issue range query
query = numericDocValuesRangeQuery
(fieldName, minBits, (max == null ? positiveInfinityBits : maxBits), minInclusive, maxInclusive);
}
}
return query;
}
public static Query numericDocValuesRangeQuery(
String field,
Number lowerValue, Number upperValue,
boolean lowerInclusive, boolean upperInclusive) {
long actualLowerValue = Long.MIN_VALUE;
if (lowerValue != null) {
actualLowerValue = lowerValue.longValue();
if (lowerInclusive == false) {
if (actualLowerValue == Long.MAX_VALUE) {
return new MatchNoDocsQuery();
}
++actualLowerValue;
}
}
long actualUpperValue = Long.MAX_VALUE;
if (upperValue != null) {
actualUpperValue = upperValue.longValue();
if (upperInclusive == false) {
if (actualUpperValue == Long.MIN_VALUE) {
return new MatchNoDocsQuery();
}
--actualUpperValue;
}
}
return NumericDocValuesField.newRangeQuery(field, actualLowerValue, actualUpperValue);
}
}

View File

@ -49,15 +49,7 @@ import org.slf4j.LoggerFactory;
* {@code DocValues} are supported for single-value cases ({@code NumericDocValues}).
* {@code FieldCache} is not supported for {@code PointField}s, so sorting, faceting, etc on these fields require the use of {@code docValues="true"} in the schema.
*/
public abstract class PointField extends PrimitiveFieldType {
public enum PointTypes {
INTEGER,
LONG,
FLOAT,
DOUBLE,
DATE
}
public abstract class PointField extends NumericFieldType {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -117,11 +109,6 @@ public abstract class PointField extends PrimitiveFieldType {
return false;
}
/**
* @return the type of this field
*/
public abstract PointTypes getType();
@Override
public abstract Query getSetQuery(QParser parser, SchemaField field, Collection<String> externalVals);
@ -137,6 +124,19 @@ public abstract class PointField extends PrimitiveFieldType {
protected abstract Query getExactQuery(SchemaField field, String externalVal);
public abstract Query getPointRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive);
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String min, String max, boolean minInclusive,
boolean maxInclusive) {
if (!field.indexed() && field.hasDocValues() && !field.multiValued()) {
return getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
} else {
return getPointRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
}
}
@Override
public String storedToReadable(IndexableField f) {
return toExternal(f);

View File

@ -84,7 +84,7 @@ import org.apache.solr.util.DateMathParser;
*/
public class TrieDateField extends TrieField implements DateValueFieldType {
{
this.type = TrieTypes.DATE;
this.type = NumberType.DATE;
}
@Override

View File

@ -52,7 +52,7 @@ import org.apache.lucene.util.mutable.MutableValueDouble;
*/
public class TrieDoubleField extends TrieField implements DoubleValueFieldType {
{
type=TrieTypes.DOUBLE;
type = NumberType.DOUBLE;
}
@Override

View File

@ -43,7 +43,6 @@ import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
import org.apache.lucene.queries.function.valuesource.IntFieldSource;
import org.apache.lucene.queries.function.valuesource.LongFieldSource;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedSetSelector;
@ -56,9 +55,7 @@ import org.apache.lucene.util.mutable.MutableValueDate;
import org.apache.lucene.util.mutable.MutableValueLong;
import org.apache.solr.common.SolrException;
import org.apache.solr.response.TextResponseWriter;
import org.apache.solr.search.FunctionRangeQuery;
import org.apache.solr.search.QParser;
import org.apache.solr.search.function.ValueSourceRangeFilter;
import org.apache.solr.uninverting.UninvertingReader.Type;
import org.apache.solr.util.DateMathParser;
import org.slf4j.Logger;
@ -84,12 +81,11 @@ import org.slf4j.LoggerFactory;
* @see org.apache.lucene.legacy.LegacyNumericRangeQuery
* @since solr 1.4
*/
public class TrieField extends PrimitiveFieldType {
public class TrieField extends NumericFieldType {
public static final int DEFAULT_PRECISION_STEP = 8;
protected int precisionStepArg = TrieField.DEFAULT_PRECISION_STEP; // the one passed in or defaulted
protected int precisionStep; // normalized
protected TrieTypes type;
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@ -107,7 +103,7 @@ public class TrieField extends PrimitiveFieldType {
if (t != null) {
try {
type = TrieTypes.valueOf(t.toUpperCase(Locale.ROOT));
type = NumberType.valueOf(t.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
"Invalid type specified in schema.xml for field: " + args.get("name"), e);
@ -139,7 +135,7 @@ public class TrieField extends PrimitiveFieldType {
}
// normal stored case
return (type == TrieTypes.DATE) ? new Date(val.longValue()) : val;
return (type == NumberType.DATE) ? new Date(val.longValue()) : val;
} else {
// multi-valued numeric docValues currently use SortedSet on the indexed terms.
BytesRef term = f.binaryValue();
@ -340,13 +336,6 @@ public class TrieField extends PrimitiveFieldType {
return precisionStepArg;
}
/**
* @return the type of this field
*/
public TrieTypes getType() {
return type;
}
@Override
public LegacyNumericType getNumericType() {
switch (type) {
@ -372,66 +361,41 @@ public class TrieField extends PrimitiveFieldType {
}
int ps = precisionStep;
Query query;
final boolean matchOnly = field.hasDocValues() && !field.indexed();
if (field.hasDocValues() && !field.indexed()) {
return getDocValuesRangeQuery(parser, field, min, max, minInclusive, maxInclusive);
}
switch (type) {
case INTEGER:
if (matchOnly) {
query = numericDocValuesRangeQuery(field.getName(),
min == null ? null : Integer.parseInt(min),
max == null ? null : Integer.parseInt(max),
minInclusive, maxInclusive);
} else {
query = LegacyNumericRangeQuery.newIntRange(field.getName(), ps,
min == null ? null : Integer.parseInt(min),
max == null ? null : Integer.parseInt(max),
minInclusive, maxInclusive);
}
query = LegacyNumericRangeQuery.newIntRange(field.getName(), ps,
min == null ? null : Integer.parseInt(min),
max == null ? null : Integer.parseInt(max),
minInclusive, maxInclusive);
break;
case FLOAT:
if (matchOnly) {
return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
} else {
query = LegacyNumericRangeQuery.newFloatRange(field.getName(), ps,
min == null ? null : Float.parseFloat(min),
max == null ? null : Float.parseFloat(max),
minInclusive, maxInclusive);
}
query = LegacyNumericRangeQuery.newFloatRange(field.getName(), ps,
min == null ? null : Float.parseFloat(min),
max == null ? null : Float.parseFloat(max),
minInclusive, maxInclusive);
break;
case LONG:
if (matchOnly) {
query = numericDocValuesRangeQuery(field.getName(),
min == null ? null : Long.parseLong(min),
max == null ? null : Long.parseLong(max),
minInclusive, maxInclusive);
} else {
query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
min == null ? null : Long.parseLong(min),
max == null ? null : Long.parseLong(max),
minInclusive, maxInclusive);
}
query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
min == null ? null : Long.parseLong(min),
max == null ? null : Long.parseLong(max),
minInclusive, maxInclusive);
break;
case DOUBLE:
if (matchOnly) {
return getRangeQueryForFloatDoubleDocValues(field, min, max, minInclusive, maxInclusive);
} else {
query = LegacyNumericRangeQuery.newDoubleRange(field.getName(), ps,
min == null ? null : Double.parseDouble(min),
max == null ? null : Double.parseDouble(max),
minInclusive, maxInclusive);
}
query = LegacyNumericRangeQuery.newDoubleRange(field.getName(), ps,
min == null ? null : Double.parseDouble(min),
max == null ? null : Double.parseDouble(max),
minInclusive, maxInclusive);
break;
case DATE:
if (matchOnly) {
query = numericDocValuesRangeQuery(field.getName(),
min == null ? null : DateMathParser.parseMath(null, min).getTime(),
max == null ? null : DateMathParser.parseMath(null, max).getTime(),
minInclusive, maxInclusive);
} else {
query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
min == null ? null : DateMathParser.parseMath(null, min).getTime(),
max == null ? null : DateMathParser.parseMath(null, max).getTime(),
minInclusive, maxInclusive);
}
query = LegacyNumericRangeQuery.newLongRange(field.getName(), ps,
min == null ? null : DateMathParser.parseMath(null, min).getTime(),
max == null ? null : DateMathParser.parseMath(null, max).getTime(),
minInclusive, maxInclusive);
break;
default:
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field");
@ -440,81 +404,6 @@ public class TrieField extends PrimitiveFieldType {
return query;
}
private static Query numericDocValuesRangeQuery(
String field,
Number lowerValue, Number upperValue,
boolean lowerInclusive, boolean upperInclusive) {
long actualLowerValue = Long.MIN_VALUE;
if (lowerValue != null) {
actualLowerValue = lowerValue.longValue();
if (lowerInclusive == false) {
if (actualLowerValue == Long.MAX_VALUE) {
return new MatchNoDocsQuery();
}
++actualLowerValue;
}
}
long actualUpperValue = Long.MAX_VALUE;
if (upperValue != null) {
actualUpperValue = upperValue.longValue();
if (upperInclusive == false) {
if (actualUpperValue == Long.MIN_VALUE) {
return new MatchNoDocsQuery();
}
--actualUpperValue;
}
}
return NumericDocValuesField.newRangeQuery(field, actualLowerValue, actualUpperValue);
}
private static long FLOAT_NEGATIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.NEGATIVE_INFINITY);
private static long DOUBLE_NEGATIVE_INFINITY_BITS = Double.doubleToLongBits(Double.NEGATIVE_INFINITY);
private static long FLOAT_POSITIVE_INFINITY_BITS = (long)Float.floatToIntBits(Float.POSITIVE_INFINITY);
private static long DOUBLE_POSITIVE_INFINITY_BITS = Double.doubleToLongBits(Double.POSITIVE_INFINITY);
private static long FLOAT_MINUS_ZERO_BITS = (long)Float.floatToIntBits(-0f);
private static long DOUBLE_MINUS_ZERO_BITS = Double.doubleToLongBits(-0d);
private static long FLOAT_ZERO_BITS = (long)Float.floatToIntBits(0f);
private static long DOUBLE_ZERO_BITS = Double.doubleToLongBits(0d);
private Query getRangeQueryForFloatDoubleDocValues(SchemaField sf, String min, String max, boolean minInclusive, boolean maxInclusive) {
Query query;
String fieldName = sf.getName();
Number minVal = min == null ? null : type == TrieTypes.FLOAT ? Float.parseFloat(min): Double.parseDouble(min);
Number maxVal = max == null ? null : type == TrieTypes.FLOAT ? Float.parseFloat(max): Double.parseDouble(max);
Long minBits =
min == null ? null : type == TrieTypes.FLOAT ? (long) Float.floatToIntBits(minVal.floatValue()): Double.doubleToLongBits(minVal.doubleValue());
Long maxBits =
max == null ? null : type == TrieTypes.FLOAT ? (long) Float.floatToIntBits(maxVal.floatValue()): Double.doubleToLongBits(maxVal.doubleValue());
long negativeInfinityBits = type == TrieTypes.FLOAT ? FLOAT_NEGATIVE_INFINITY_BITS : DOUBLE_NEGATIVE_INFINITY_BITS;
long positiveInfinityBits = type == TrieTypes.FLOAT ? FLOAT_POSITIVE_INFINITY_BITS : DOUBLE_POSITIVE_INFINITY_BITS;
long minusZeroBits = type == TrieTypes.FLOAT ? FLOAT_MINUS_ZERO_BITS : DOUBLE_MINUS_ZERO_BITS;
long zeroBits = type == TrieTypes.FLOAT ? FLOAT_ZERO_BITS : DOUBLE_ZERO_BITS;
// If min is negative (or -0d) and max is positive (or +0d), then issue a FunctionRangeQuery
if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
(maxVal == null || (maxVal.doubleValue() > 0d || maxBits == zeroBits))) {
ValueSource vs = getValueSource(sf, null);
query = new FunctionRangeQuery(new ValueSourceRangeFilter(vs, min, max, minInclusive, maxInclusive));
} else { // If both max and min are negative (or -0d), then issue range query with max and min reversed
if ((minVal == null || minVal.doubleValue() < 0d || minBits == minusZeroBits) &&
(maxVal != null && (maxVal.doubleValue() < 0d || maxBits == minusZeroBits))) {
query = numericDocValuesRangeQuery
(fieldName, maxBits, (min == null ? negativeInfinityBits : minBits), maxInclusive, minInclusive);
} else { // If both max and min are positive, then issue range query
query = numericDocValuesRangeQuery
(fieldName, minBits, (max == null ? positiveInfinityBits : maxBits), minInclusive, maxInclusive);
}
}
return query;
}
@Override
public Query getFieldQuery(QParser parser, SchemaField field, String externalVal) {
if (!field.indexed() && field.hasDocValues()) {
@ -579,7 +468,7 @@ public class TrieField extends PrimitiveFieldType {
@Override
public String toExternal(IndexableField f) {
return (type == TrieTypes.DATE)
return (type == NumberType.DATE)
? ((Date) toObject(f)).toInstant().toString()
: toObject(f).toString();
}
@ -792,15 +681,6 @@ public class TrieField extends PrimitiveFieldType {
}
}
public enum TrieTypes {
INTEGER,
LONG,
FLOAT,
DOUBLE,
DATE
}
static final String INT_PREFIX = new String(new char[]{LegacyNumericUtils.SHIFT_START_INT});
static final String LONG_PREFIX = new String(new char[]{LegacyNumericUtils.SHIFT_START_LONG});
@ -863,7 +743,6 @@ class TrieDateFieldSource extends LongFieldSource {
public long externalToLong(String extVal) {
return DateMathParser.parseMath(null, extVal).getTime();
}
}

View File

@ -52,7 +52,7 @@ import org.apache.lucene.util.mutable.MutableValueFloat;
*/
public class TrieFloatField extends TrieField implements FloatValueFieldType {
{
type=TrieTypes.FLOAT;
type = NumberType.FLOAT;
}
@Override

View File

@ -45,7 +45,7 @@ import org.apache.lucene.util.mutable.MutableValueInt;
*/
public class TrieIntField extends TrieField implements IntValueFieldType {
{
type=TrieTypes.INTEGER;
type = NumberType.INTEGER;
}
@Override

View File

@ -45,7 +45,7 @@ import org.apache.lucene.util.mutable.MutableValueLong;
*/
public class TrieLongField extends TrieField implements LongValueFieldType {
{
type=TrieTypes.LONG;
type = NumberType.LONG;
}
@Override

View File

@ -98,6 +98,7 @@ import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.EnumField;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.NumericFieldType;
import org.apache.solr.schema.PointField;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.schema.TrieDateField;
@ -823,7 +824,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
}
Object newVal = val;
if (schemaField.getType().isPointField()) {
PointField.PointTypes type = ((PointField)schemaField.getType()).getType();
NumericFieldType.NumberType type = ((PointField)schemaField.getType()).getType();
switch (type) {
case INTEGER:
newVal = val.intValue();

View File

@ -70,7 +70,7 @@ class GroupConverter {
for (SearchGroup<BytesRef> original : values) {
SearchGroup<MutableValue> converted = new SearchGroup<MutableValue>();
converted.sortValues = original.sortValues; // ?
TrieField.TrieTypes type = ((TrieField)fieldType).getType();
TrieField.NumberType type = ((TrieField)fieldType).getType();
final MutableValue v;
switch (type) {
case INTEGER:

View File

@ -79,6 +79,10 @@
<dynamicField name="*_p_l_dv_ns" type="plong" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_d_dv_ns" type="pdouble" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_f_dv_ns" type="pfloat" indexed="true" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_i_ni_ns_dv" type="pint" indexed="false" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_l_ni_ns_dv" type="plong" indexed="false" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_d_ni_ns_dv" type="pdouble" indexed="false" stored="false" docValues="true" useDocValuesAsStored="true"/>
<dynamicField name="*_p_f_ni_ns_dv" type="pfloat" indexed="false" stored="false" docValues="true" useDocValuesAsStored="true"/>
</fields>

View File

@ -59,6 +59,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
doTestIntPointFieldExactQuery("number_p_i", false);
doTestIntPointFieldExactQuery("number_p_i_mv", false);
doTestIntPointFieldExactQuery("number_p_i_ni_dv", false);
doTestIntPointFieldExactQuery("number_p_i_ni_ns_dv", false);
// uncomment once MultiValued docValues are supported in PointFields
// doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", false);
}
@ -74,6 +75,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
@Test
public void testIntPointFieldRangeQuery() throws Exception {
doTestIntPointFieldRangeQuery("number_p_i", "int", false);
doTestIntPointFieldRangeQuery("number_p_i_ni_ns_dv", "int", false);
}
@Test
@ -235,6 +237,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
doTestFloatPointFieldExactQuery("number_p_d");
doTestFloatPointFieldExactQuery("number_p_d_mv");
doTestFloatPointFieldExactQuery("number_p_d_ni_dv");
doTestFloatPointFieldExactQuery("number_p_d_ni_ns_dv");
// TODO enable once MuultiValued docValues are supported with PointFields
// doTestFloatPointFieldExactQuery("number_p_d_ni_mv_dv");
}
@ -258,6 +261,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
@Test
public void testDoublePointFieldRangeQuery() throws Exception {
doTestFloatPointFieldRangeQuery("number_p_d", "double", true);
doTestFloatPointFieldRangeQuery("number_p_d_ni_ns_dv", "double", true);
}
@Test
@ -457,6 +461,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
doTestFloatPointFieldExactQuery("number_p_f");
doTestFloatPointFieldExactQuery("number_p_f_mv");
doTestFloatPointFieldExactQuery("number_p_f_ni_dv");
doTestFloatPointFieldExactQuery("number_p_f_ni_ns_dv");
// doTestFloatPointFieldExactQuery("number_p_f_ni_mv_dv");
}
@ -479,6 +484,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
@Test
public void testFloatPointFieldRangeQuery() throws Exception {
doTestFloatPointFieldRangeQuery("number_p_f", "float", false);
doTestFloatPointFieldRangeQuery("number_p_f_ni_ns_dv", "float", false);
}
@Test
@ -551,6 +557,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
doTestIntPointFieldExactQuery("number_p_l", true);
doTestIntPointFieldExactQuery("number_p_l_mv", true);
doTestIntPointFieldExactQuery("number_p_l_ni_dv", true);
doTestIntPointFieldExactQuery("number_p_l_ni_ns_dv", true);
// doTestIntPointFieldExactQuery("number_p_i_ni_mv_dv", true);
}
@ -565,6 +572,7 @@ public class TestPointFields extends SolrTestCaseJ4 {
@Test
public void testLongPointFieldRangeQuery() throws Exception {
doTestIntPointFieldRangeQuery("number_p_l", "long", true);
doTestIntPointFieldRangeQuery("number_p_l_ni_ns_dv", "long", true);
}
@Test