SOLR-3413: support multiple copies in return fields

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1330568 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan McKinley 2012-04-25 21:26:51 +00:00
parent d1562ef683
commit 14560553b4
4 changed files with 85 additions and 30 deletions

View File

@ -26,37 +26,30 @@ import org.apache.solr.request.SolrQueryRequest;
*
* @since solr 4.0
*/
public class RenameFieldsTransformer extends DocTransformer
public class RenameFieldTransformer extends DocTransformer
{
final NamedList<String> rename;
final String from;
final String to;
final boolean copy;
public RenameFieldsTransformer( NamedList<String> rename )
public RenameFieldTransformer( String from, String to, boolean copy )
{
this.rename = rename;
this.from = from;
this.to = to;
this.copy = copy;
}
@Override
public String getName()
{
StringBuilder str = new StringBuilder();
str.append( "Rename[" );
for( int i=0; i< rename.size(); i++ ) {
if( i > 0 ) {
str.append( "," );
}
str.append( rename.getName(i) ).append( ">>" ).append( rename.getVal( i ) );
}
str.append( "]" );
return str.toString();
return "Rename["+from+">>"+to+"]";
}
@Override
public void transform(SolrDocument doc, int docid) {
for( int i=0; i<rename.size(); i++ ) {
Object v = doc.remove( rename.getName(i) );
Object v = (copy)?doc.get(from) : doc.remove( from );
if( v != null ) {
doc.setField(rename.getVal(i), v);
}
doc.setField(to, v);
}
}
}

View File

@ -32,7 +32,7 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.transform.DocTransformer;
import org.apache.solr.response.transform.DocTransformers;
import org.apache.solr.response.transform.RenameFieldsTransformer;
import org.apache.solr.response.transform.RenameFieldTransformer;
import org.apache.solr.response.transform.ScoreAugmenter;
import org.apache.solr.response.transform.TransformerFactory;
import org.apache.solr.response.transform.ValueSourceAugmenter;
@ -62,6 +62,9 @@ public class ReturnFields
// This will include pseudo fields, lucene fields, and matching globs
private Set<String> okFieldNames = new HashSet<String>();
// The list of explicitly requested fields
private Set<String> reqFieldNames = null;
private DocTransformer transformer;
private boolean _wantsScore = false;
private boolean _wantsAllFields = false;
@ -111,11 +114,24 @@ public class ReturnFields
for (String fieldList : fl) {
add(fieldList,rename,augmenters,req);
}
if( rename.size() > 0 ) {
for( int i=0; i<rename.size(); i++ ) {
okFieldNames.add( rename.getVal(i) );
String from = rename.getName(i);
String to = rename.getVal(i);
okFieldNames.add( to );
boolean copy = (reqFieldNames!=null && reqFieldNames.contains(from));
if(!copy) {
// Check that subsequent copy/rename requests have the field they need to copy
for(int j=i+1; j<rename.size(); j++) {
if(from.equals(rename.getName(j))) {
rename.setName(j, to); // copy from the current target
if(reqFieldNames==null) {
reqFieldNames = new HashSet<String>();
}
augmenters.addTransformer( new RenameFieldsTransformer( rename ) );
reqFieldNames.add(to); // don't rename our current target
}
}
}
augmenters.addTransformer( new RenameFieldTransformer( from, to, copy ) );
}
if( !_wantsAllFields ) {
@ -348,13 +364,21 @@ public class ReturnFields
private void addField( String field, String key, DocTransformers augmenters, SolrQueryRequest req )
{
String disp = (key==null) ? field : key;
if(key==null) {
if(reqFieldNames==null) {
reqFieldNames = new HashSet<String>();
}
reqFieldNames.add(field);
}
fields.add(field); // need to put in the map to maintain order for things like CSVResponseWriter
okFieldNames.add( field );
okFieldNames.add( key );
// a valid field name
if(SCORE.equals(field)) {
_wantsScore = true;
String disp = (key==null) ? field : key;
augmenters.addTransformer( new ScoreAugmenter( disp ) );
}
}

View File

@ -18,6 +18,8 @@
package org.apache.solr.search;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.transform.*;
import org.junit.BeforeClass;
import org.junit.Test;
@ -49,6 +51,46 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
assertU(commit());
}
@Test
public void testCopyRename() throws Exception {
// original
assertQ(req("q","id:1", "fl","id")
,"//*[@numFound='1'] "
,"*[count(//doc/str)=1] "
,"*//doc[1]/str[1][.='1'] "
);
// rename
assertQ(req("q","id:1", "fl","xxx:id")
,"//*[@numFound='1'] "
,"*[count(//doc/str)=1] "
,"*//doc[1]/str[1][.='1'] "
);
// original and copy
assertQ(req("q","id:1", "fl","id,xxx:id")
,"//*[@numFound='1'] "
,"*[count(//doc/str)=2] "
,"*//doc[1]/str[1][.='1'] "
,"*//doc[1]/str[2][.='1'] "
);
assertQ(req("q","id:1", "fl","xxx:id,id")
,"//*[@numFound='1'] "
,"*[count(//doc/str)=2] "
,"*//doc[1]/str[1][.='1'] "
,"*//doc[1]/str[2][.='1'] "
);
// two copies
assertQ(req("q","id:1", "fl","xxx:id,yyy:id")
,"//*[@numFound='1'] "
,"*[count(//doc/str)=2] "
,"*//doc[1]/str[1][.='1'] "
,"*//doc[1]/str[2][.='1'] "
);
}
@Test
public void testSeparators() {
ReturnFields rf = new ReturnFields( req("fl", "id name test subject score") );
@ -202,7 +244,6 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
assertTrue(rf.wantsField("newSubject"));
assertFalse(rf.wantsField("xxx"));
assertFalse(rf.wantsAllFields());
assertTrue( rf.getTransformer() instanceof RenameFieldsTransformer);
rf = new ReturnFields( req("fl", "newId:id newName:name newTest:test newSubject:subject score") );
assertTrue(rf.wantsField("id"));
@ -216,7 +257,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
assertFalse(rf.wantsField("xxx"));
assertFalse(rf.wantsAllFields());
assertTrue( rf.getTransformer() instanceof DocTransformers);
assertEquals(2, ((DocTransformers)rf.getTransformer()).size());
assertEquals(5, ((DocTransformers)rf.getTransformer()).size()); // 4 rename and score
}
// hyphens in field names are not supported in all contexts, but we wanted

View File

@ -31,9 +31,6 @@ public class StartSolrJetty
{
//System.setProperty("solr.solr.home", "../../../example/solr");
javax.servlet.FilterRegistration xx;
Server server = new Server();
SocketConnector connector = new SocketConnector();
// Set some timeout options to make debugging easier.