Merged revision(s) 1683134 from lucene/dev/branches/branch_5x:

SOLR-7622: let DocTransformers request extra fields
........


git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1683162 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan McKinley 2015-06-02 19:16:00 +00:00
parent cecebbc750
commit c726e72cfc
6 changed files with 211 additions and 1 deletions

View File

@ -84,6 +84,10 @@ New Features
* SOLR-7389: Expose znodeVersion property for each of the collections returned for the clusterstatus * SOLR-7389: Expose znodeVersion property for each of the collections returned for the clusterstatus
operation in the collections API (Marius Grama via shalin) 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 Bug Fixes
---------------------- ----------------------

View File

@ -17,6 +17,7 @@ package org.apache.solr.response;
* limitations under the License. * limitations under the License.
*/ */
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.StorableField; import org.apache.lucene.index.StorableField;
import org.apache.lucene.index.StoredDocument; import org.apache.lucene.index.StoredDocument;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
@ -54,4 +55,15 @@ public class ResponseWriterUtil {
} }
return out; 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;
}
} }

View File

@ -20,7 +20,9 @@ package org.apache.solr.response.transform;
import java.io.IOException; import java.io.IOException;
import org.apache.solr.common.SolrDocument; 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 * 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; 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 @Override
public String toString() { public String toString() {
return getName(); return getName();

View File

@ -264,6 +264,14 @@ public class SolrReturnFields extends ReturnFields {
MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs ); MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs );
DocTransformer t = factory.create(disp, augmenterParams, req); DocTransformer t = factory.create(disp, augmenterParams, req);
if(t!=null) { 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 ); augmenters.addTransformer( t );
} }
} }

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
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.
-->
<!--
This is a stripped down config file used for a simple example...
It is *not* a good example to work from.
-->
<config>
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
<indexConfig>
<useCompoundFile>${useCompoundFile:false}</useCompoundFile>
</indexConfig>
<dataDir>${solr.data.dir:}</dataDir>
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
<updateHandler class="solr.DirectUpdateHandler2">
<updateLog>
<str name="dir">${solr.data.dir:}</str>
</updateLog>
</updateHandler>
<transformer name="custom" class="org.apache.solr.response.TestCustomDocTransformer$CustomTransformerFactory" />
<requestHandler name="/select" class="solr.StandardRequestHandler"/>
<requestDispatcher handleSelect="true" >
<requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />
</requestDispatcher>
<requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />
<!-- config for the admin interface -->
<admin>
<defaultQuery>solr</defaultQuery>
</admin>
</config>

View File

@ -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<max; i++) {
SolrInputDocument sdoc = new SolrInputDocument();
sdoc.addField("id", i);
sdoc.addField("subject", "xx");
sdoc.addField("title", "title_"+i);
updateJ(jsonAdd(sdoc), null);
}
assertU(commit());
assertQ(req("q", "*:*"), "//*[@numFound='" + max + "']");
assertQ( req(
"q", "*:*",
"fl", "id,out:[custom extra=subject,title]"),
// Check that the concatinated fields make it in the results
"//*[@numFound='" + max + "']",
"//str[.='xx#title_0#']",
"//str[.='xx#title_1#']",
"//str[.='xx#title_2#']",
"//str[.='xx#title_3#']");
}
public static class CustomTransformerFactory extends TransformerFactory {
@Override
public DocTransformer create(String field, SolrParams params, SolrQueryRequest req) {
String[] extra = null;
String ext = params.get("extra");
if(ext!=null) {
extra = Strings.split(ext, ',');
}
return new CustomTransformer(field, extra);
}
}
public static class CustomTransformer extends DocTransformer {
final String name;
final String[] extra;
final StringBuilder str = new StringBuilder();
public CustomTransformer(String name, String[] extra) {
this.name = name;
this.extra = extra;
}
@Override
public String getName() {
return "custom";
}
@Override
public String[] getExtraRequestFields() {
return extra;
}
/**
* This transformer simply concatinates the values of multipe fields
*/
@Override
public void transform(SolrDocument doc, int docid) throws IOException {
str.setLength(0);
for(String s : extra) {
String v = ResponseWriterUtil.getAsString(s, doc);
str.append(v).append('#');
}
System.out.println( "HELLO: "+str );
doc.setField(name, str.toString());
}
}
}