From 57b64f26846294599f4f8016ce5566dffe5f4de2 Mon Sep 17 00:00:00 2001 From: Erick Erickson Date: Mon, 27 May 2019 08:34:48 -0700 Subject: [PATCH] SOLR-12562: Reverting Clean up RealTimeGetComponent.toSolrDoc (sha 97e7d8a3d78779bb26148ed1849ba1acdf44c6c5 and 15aa9dfb3de104c3cd880e1d59f835932c17e1ff) --- solr/CHANGES.txt | 2 - .../component/RealTimeGetComponent.java | 59 ++++++++++++++----- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index d67718a45de..8d665fe93c7 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -112,8 +112,6 @@ Other Changes * SOLR-13467: Include the S2 Geometry lib to make it simpler to use prefixTree="s2" on a Geo3D spatial field. Improved documentation on Geo3D too. (David Smiley) -* SOLR-12562: Clean up RealTimeGetComponent.toSolrDoc (Erick Erickson) - ================== 8.1.1 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. diff --git a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java index 5c730956e71..f03cba46800 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java @@ -763,34 +763,61 @@ public class RealTimeGetComponent extends SearchComponent SolrDocument out = new SolrDocument(); for( IndexableField f : doc.getFields() ) { // Make sure multivalued fields are represented as lists - + Object existing = out.get(f.name()); + if (existing == null) { SchemaField sf = schema.getFieldOrNull(f.name()); - if (sf == null) { - // This is unexpected! - log.warn("schema.getFieldOrNull returned null {}, this is unexpected! ", f.name()); - out.setField(f.name(), f.stringValue()); - continue; - } // don't return copyField targets - if (schema.isCopyFieldTarget(sf)) continue; + if (sf != null && schema.isCopyFieldTarget(sf)) continue; - if (out.get(f.name()) != null) { - out.addField(f.name(), sf.getType().toObject(f)); - continue; - } - - if (sf.multiValued()) { + if (sf != null && sf.multiValued()) { List vals = new ArrayList<>(); - vals.add(sf.getType().toObject(f)); + if (f.fieldType().docValuesType() == DocValuesType.SORTED_NUMERIC) { + // SORTED_NUMERICS store sortable bits version of the value, need to retrieve the original + vals.add(sf.getType().toObject(f)); // (will materialize by side-effect) + } else { + vals.add( materialize(f) ); + } out.setField(f.name(), vals); } else { - out.setField(f.name(), sf.getType().toObject(f)); + out.setField( f.name(), materialize(f) ); + } + } + else { + out.addField( f.name(), materialize(f) ); } } return out; } + /** + * Ensure we don't have {@link org.apache.lucene.document.LazyDocument.LazyField} or equivalent. + * It can pose problems if the searcher is about to be closed and we haven't fetched a value yet. + */ + private static IndexableField materialize(IndexableField in) { + if (in instanceof Field) { // already materialized + return in; + } + return new ClonedField(in); + } + + private static class ClonedField extends Field { // TODO Lucene Field has no copy constructor; maybe it should? + ClonedField(IndexableField in) { + super(in.name(), in.fieldType()); + this.fieldsData = in.numericValue(); + if (this.fieldsData == null) { + this.fieldsData = in.binaryValue(); + if (this.fieldsData == null) { + this.fieldsData = in.stringValue(); + if (this.fieldsData == null) { + // fallback: + assert false : in; // unexpected + } + } + } + } + } + /** * Converts a SolrInputDocument to SolrDocument, using an IndexSchema instance. * @lucene.experimental