From 82a537795ff9e85cd6834d6f46c41851b435bf7c Mon Sep 17 00:00:00 2001 From: yonik Date: Wed, 23 Mar 2016 11:56:00 -0400 Subject: [PATCH] SOLR-8886: fix TrieField.toObject(IndexableField) for docValues --- solr/CHANGES.txt | 3 ++ .../org/apache/solr/schema/TrieField.java | 40 ++++++++++++++++++- .../collection1/conf/schema-docValues.xml | 11 +++++ .../org/apache/solr/schema/DocValuesTest.java | 22 ++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 634f218dbb7..7e0fbe477ed 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -345,6 +345,9 @@ Bug Fixes numeric field. For more complex functions, FunctionValues.exists() must also return true for the document to match. (yonik) +* SOLR-8886: Fix TrieField.toObject(IndexableField) to work for field with docValues + enabled. (yonik) + Optimizations ---------------------- * SOLR-7876: Speed up queries and operations that use many terms when timeAllowed has not been 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 1580b0037ed..506d8ad9b9a 100644 --- a/solr/core/src/java/org/apache/solr/schema/TrieField.java +++ b/solr/core/src/java/org/apache/solr/schema/TrieField.java @@ -33,6 +33,7 @@ import org.apache.lucene.document.LegacyIntField; import org.apache.lucene.document.LegacyLongField; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.SortedSetDocValuesField; +import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; @@ -121,11 +122,46 @@ public class TrieField extends PrimitiveFieldType { public Object toObject(IndexableField f) { final Number val = f.numericValue(); if (val != null) { + + if (f.fieldType().stored() == false && f.fieldType().docValuesType() == DocValuesType.NUMERIC ) { + long bits = val.longValue(); + switch (type) { + case INTEGER: + return (int)bits; + case FLOAT: + return Float.intBitsToFloat((int)bits); + case LONG: + return bits; + case DOUBLE: + return Double.longBitsToDouble(bits); + case DATE: + return new Date(bits); + default: + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name()); + } + } + + // normal stored case return (type == TrieTypes.DATE) ? new Date(val.longValue()) : val; } else { - // the old BinaryField encoding is no longer supported - return badFieldString(f); + // multi-valued numeric docValues currently use SortedSet on the indexed terms. + BytesRef term = f.binaryValue(); + switch (type) { + case INTEGER: + return LegacyNumericUtils.prefixCodedToInt(term); + case FLOAT: + return NumericUtils.sortableIntToFloat(LegacyNumericUtils.prefixCodedToInt(term)); + case LONG: + return LegacyNumericUtils.prefixCodedToLong(term); + case DOUBLE: + return NumericUtils.sortableLongToDouble(LegacyNumericUtils.prefixCodedToLong(term)); + case DATE: + return new Date(LegacyNumericUtils.prefixCodedToLong(term)); + default: + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown type for trie field: " + f.name()); + } } + } @Override diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-docValues.xml b/solr/core/src/test-files/solr/collection1/conf/schema-docValues.xml index cbbdf6ed0ae..680ac042103 100644 --- a/solr/core/src/test-files/solr/collection1/conf/schema-docValues.xml +++ b/solr/core/src/test-files/solr/collection1/conf/schema-docValues.xml @@ -67,6 +67,17 @@ + + + + + + + + + + + id diff --git a/solr/core/src/test/org/apache/solr/schema/DocValuesTest.java b/solr/core/src/test/org/apache/solr/schema/DocValuesTest.java index f1d0196c226..2537c8f0f6d 100644 --- a/solr/core/src/test/org/apache/solr/schema/DocValuesTest.java +++ b/solr/core/src/test/org/apache/solr/schema/DocValuesTest.java @@ -16,6 +16,7 @@ */ package org.apache.solr.schema; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.DocValuesType; import org.apache.lucene.index.FieldInfos; @@ -33,6 +34,7 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; @@ -102,12 +104,32 @@ public class DocValuesTest extends SolrTestCaseJ4 { values = longDv.getType().getValueSource(longDv, null).getValues(null, searcher.getLeafReader().leaves().get(0)); assertEquals(4L, values.longVal(0)); assertEquals(4L, values.objectVal(0)); + + // check reversability of created fields + tstToObj(schema.getField("floatdv"), -1.5f); + tstToObj(schema.getField("floatdvs"), -1.5f); + tstToObj(schema.getField("doubledv"), -1.5d); + tstToObj(schema.getField("doubledvs"), -1.5d); + tstToObj(schema.getField("intdv"), -7); + tstToObj(schema.getField("intdvs"), -7); + tstToObj(schema.getField("longdv"), -11L); + tstToObj(schema.getField("longdvs"), -11L); + tstToObj(schema.getField("datedv"), new Date(1000)); + tstToObj(schema.getField("datedvs"), new Date(1000)); + } finally { searcherRef.decref(); } } } + private void tstToObj(SchemaField sf, Object o) { + List fields = sf.createFields(o, 1.0f); + for (IndexableField field : fields) { + assertEquals( sf.getType().toObject(field), o); + } + } + public void testDocValuesSorting() { assertU(adoc("id", "1", "floatdv", "2", "intdv", "3", "doubledv", "4", "longdv", "5", "datedv", "1995-12-31T23:59:59.999Z", "stringdv", "b")); assertU(adoc("id", "2", "floatdv", "5", "intdv", "4", "doubledv", "3", "longdv", "2", "datedv", "1997-12-31T23:59:59.999Z", "stringdv", "a"));