diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 4d3239b2ad8..f38c0498644 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -84,6 +84,10 @@ New Features
* SOLR-7389: Expose znodeVersion property for each of the collections returned for the clusterstatus
operation in the collections API (Marius Grama via shalin)
+* SOLR-7622: A DocTransformer can now request fields from the SolrIndexSearcher that are not
+ necessarily returned in the file SolrDocument by returning a list of fields from
+ DocTransformer#getExtraRequestFields (ryan)
+
Bug Fixes
----------------------
diff --git a/solr/core/src/java/org/apache/solr/response/ResponseWriterUtil.java b/solr/core/src/java/org/apache/solr/response/ResponseWriterUtil.java
index 69d3021e111..d469b2ce0ca 100644
--- a/solr/core/src/java/org/apache/solr/response/ResponseWriterUtil.java
+++ b/solr/core/src/java/org/apache/solr/response/ResponseWriterUtil.java
@@ -17,6 +17,7 @@ package org.apache.solr.response;
* limitations under the License.
*/
+import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.StorableField;
import org.apache.lucene.index.StoredDocument;
import org.apache.solr.common.SolrDocument;
@@ -54,4 +55,15 @@ public class ResponseWriterUtil {
}
return out;
}
+
+ public static String getAsString(String field, SolrDocument doc) {
+ Object v = doc.getFirstValue(field);
+ if(v != null) {
+ if(v instanceof StoredField) {
+ return ((StoredField)v).stringValue();
+ }
+ return v.toString();
+ }
+ return null;
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/response/transform/DocTransformer.java b/solr/core/src/java/org/apache/solr/response/transform/DocTransformer.java
index 183042dc035..a28c3251746 100644
--- a/solr/core/src/java/org/apache/solr/response/transform/DocTransformer.java
+++ b/solr/core/src/java/org/apache/solr/response/transform/DocTransformer.java
@@ -20,7 +20,9 @@ package org.apache.solr.response.transform;
import java.io.IOException;
import org.apache.solr.common.SolrDocument;
-import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.QueryResponseWriter;
+import org.apache.solr.response.ResponseWriterUtil;
+import org.apache.solr.search.SolrIndexSearcher;
/**
* A DocTransformer can add, remove or alter a Document before it is written out to the Response. For instance, there are implementations
@@ -57,6 +59,19 @@ public abstract class DocTransformer
*/
public abstract void transform(SolrDocument doc, int docid) throws IOException;
+ /**
+ * When a transformer needs access to fields that are not automaticaly derived from the
+ * input fields names, this option lets us explicitly say the field names that we hope
+ * will be in the SolrDocument. These fields will be requestd from the
+ * {@link SolrIndexSearcher} but may or may not be returned in the final
+ * {@link QueryResponseWriter}
+ *
+ * @return a list of extra lucene fields
+ */
+ public String[] getExtraRequestFields() {
+ return null;
+ }
+
@Override
public String toString() {
return getName();
diff --git a/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java b/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java
index 61271d997da..0307910b891 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrReturnFields.java
@@ -264,6 +264,14 @@ public class SolrReturnFields extends ReturnFields {
MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs );
DocTransformer t = factory.create(disp, augmenterParams, req);
if(t!=null) {
+ if(!_wantsAllFields) {
+ String[] extra = t.getExtraRequestFields();
+ if(extra!=null) {
+ for(String f : extra) {
+ fields.add(f); // also request this field from IndexSearcher
+ }
+ }
+ }
augmenters.addTransformer( t );
}
}
diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-doctransformers.xml b/solr/core/src/test-files/solr/collection1/conf/solrconfig-doctransformers.xml
new file mode 100644
index 00000000000..5a6681f5073
--- /dev/null
+++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-doctransformers.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+ ${tests.luceneMatchVersion:LUCENE_CURRENT}
+
+ ${useCompoundFile:false}
+
+ ${solr.data.dir:}
+
+
+
+
+ ${solr.data.dir:}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ solr
+
+
+
+
diff --git a/solr/core/src/test/org/apache/solr/response/TestCustomDocTransformer.java b/solr/core/src/test/org/apache/solr/response/TestCustomDocTransformer.java
new file mode 100644
index 00000000000..dab99df1517
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/response/TestCustomDocTransformer.java
@@ -0,0 +1,118 @@
+package org.apache.solr.response;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.transform.DocTransformer;
+import org.apache.solr.response.transform.TransformerFactory;
+import org.bouncycastle.util.Strings;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestCustomDocTransformer extends SolrTestCaseJ4 {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ initCore("solrconfig-doctransformers.xml","schema.xml");
+ }
+
+ @After
+ public void cleanup() throws Exception {
+ assertU(delQ("*:*"));
+ assertU(commit());
+ }
+
+ @Test
+ public void testCustomTransformer() throws Exception {
+ // Build a simple index
+ int max = 10;
+ for(int i=0; i