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