Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 448EA200C03 for ; Sat, 21 Jan 2017 23:59:02 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 37EF0160B4A; Sat, 21 Jan 2017 22:59:02 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 8D673160B42 for ; Sat, 21 Jan 2017 23:59:00 +0100 (CET) Received: (qmail 78417 invoked by uid 500); 21 Jan 2017 22:58:59 -0000 Mailing-List: contact commits-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@lucene.apache.org Delivered-To: mailing list commits@lucene.apache.org Received: (qmail 78408 invoked by uid 99); 21 Jan 2017 22:58:59 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 21 Jan 2017 22:58:59 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 77577DFB0E; Sat, 21 Jan 2017 22:58:59 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: ishan@apache.org To: commits@lucene.apache.org Message-Id: <42d41d480d434ff08d86ddcfca208fbc@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: lucene-solr:master: SOLR-10011: Refactor PointField & TrieField to now have a common base class, NumericFieldType. Date: Sat, 21 Jan 2017 22:58:59 +0000 (UTC) archived-at: Sat, 21 Jan 2017 22:59:02 -0000 Repository: lucene-solr Updated Branches: refs/heads/master 49fa7b0dd -> 285a1013a 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. Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/285a1013 Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/285a1013 Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/285a1013 Branch: refs/heads/master Commit: 285a1013ad04dd1cd5e5e41ffa93a87fe862c152 Parents: 49fa7b0 Author: Ishan Chattopadhyaya Authored: Sun Jan 22 04:27:11 2017 +0530 Committer: Ishan Chattopadhyaya Committed: Sun Jan 22 04:27:11 2017 +0530 ---------------------------------------------------------------------- solr/CHANGES.txt | 5 + .../apache/solr/schema/DoublePointField.java | 11 +- .../org/apache/solr/schema/FloatPointField.java | 11 +- .../org/apache/solr/schema/IntPointField.java | 10 +- .../org/apache/solr/schema/LongPointField.java | 11 +- .../apache/solr/schema/NumericFieldType.java | 151 ++++++++++++++++ .../java/org/apache/solr/schema/PointField.java | 28 +-- .../org/apache/solr/schema/TrieDateField.java | 2 +- .../org/apache/solr/schema/TrieDoubleField.java | 2 +- .../java/org/apache/solr/schema/TrieField.java | 179 +++---------------- .../org/apache/solr/schema/TrieFloatField.java | 2 +- .../org/apache/solr/schema/TrieIntField.java | 2 +- .../org/apache/solr/schema/TrieLongField.java | 2 +- .../apache/solr/search/SolrIndexSearcher.java | 3 +- .../distributed/command/GroupConverter.java | 2 +- .../solr/collection1/conf/schema-point.xml | 4 + .../org/apache/solr/schema/TestPointFields.java | 8 + 17 files changed, 239 insertions(+), 194 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/CHANGES.txt ---------------------------------------------------------------------- diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 748125a..abd2983 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -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. http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/DoublePointField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java index c393dfe..b9a7311 100644 --- a/solr/core/src/java/org/apache/solr/schema/DoublePointField.java +++ b/solr/core/src/java/org/apache/solr/schema/DoublePointField.java @@ -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; - } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/FloatPointField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java index 766c6e9..7b866fc 100644 --- a/solr/core/src/java/org/apache/solr/schema/FloatPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/FloatPointField.java @@ -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; - } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/IntPointField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/IntPointField.java b/solr/core/src/java/org/apache/solr/schema/IntPointField.java index 2271282..3e74241 100644 --- a/solr/core/src/java/org/apache/solr/schema/IntPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/IntPointField.java @@ -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; - } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/LongPointField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/LongPointField.java b/solr/core/src/java/org/apache/solr/schema/LongPointField.java index f3fca3c..80f3cf7 100644 --- a/solr/core/src/java/org/apache/solr/schema/LongPointField.java +++ b/solr/core/src/java/org/apache/solr/schema/LongPointField.java @@ -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; - } } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java new file mode 100644 index 0000000..404693d --- /dev/null +++ b/solr/core/src/java/org/apache/solr/schema/NumericFieldType.java @@ -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); + } +} http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/PointField.java ---------------------------------------------------------------------- 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 a2dd8a8..9b1ed38 100644 --- a/solr/core/src/java/org/apache/solr/schema/PointField.java +++ b/solr/core/src/java/org/apache/solr/schema/PointField.java @@ -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 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); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieDateField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieDateField.java b/solr/core/src/java/org/apache/solr/schema/TrieDateField.java index 209c581..77980a7 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieDateField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieDateField.java @@ -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 http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java b/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java index 7faa38c..b610e6e 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieDoubleField.java @@ -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 http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieField.java b/solr/core/src/java/org/apache/solr/schema/TrieField.java index 57dbeff..e470155 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieField.java @@ -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(); } - } http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java b/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java index 13b9141..b069810 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieFloatField.java @@ -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 http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieIntField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieIntField.java b/solr/core/src/java/org/apache/solr/schema/TrieIntField.java index d89dd0d..6d4d7cd 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieIntField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieIntField.java @@ -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 http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/schema/TrieLongField.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/schema/TrieLongField.java b/solr/core/src/java/org/apache/solr/schema/TrieLongField.java index c3a5440..a93d0ce 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieLongField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieLongField.java @@ -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 http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java index 7c56311..3f7d511 100644 --- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -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(); http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java ---------------------------------------------------------------------- diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java index 2a5827d..a9849d5 100644 --- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java +++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/GroupConverter.java @@ -70,7 +70,7 @@ class GroupConverter { for (SearchGroup original : values) { SearchGroup converted = new SearchGroup(); converted.sortValues = original.sortValues; // ? - TrieField.TrieTypes type = ((TrieField)fieldType).getType(); + TrieField.NumberType type = ((TrieField)fieldType).getType(); final MutableValue v; switch (type) { case INTEGER: http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/test-files/solr/collection1/conf/schema-point.xml ---------------------------------------------------------------------- diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml index ca37ff5..053d39b 100644 --- a/solr/core/src/test-files/solr/collection1/conf/schema-point.xml +++ b/solr/core/src/test-files/solr/collection1/conf/schema-point.xml @@ -79,6 +79,10 @@ + + + + http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/285a1013/solr/core/src/test/org/apache/solr/schema/TestPointFields.java ---------------------------------------------------------------------- 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 91a7b49..75d142d 100644 --- a/solr/core/src/test/org/apache/solr/schema/TestPointFields.java +++ b/solr/core/src/test/org/apache/solr/schema/TestPointFields.java @@ -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