SOLR-4671: CSV writer now supports pseudo fields

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1468549 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Ryan McKinley 2013-04-16 18:34:22 +00:00
parent dd28755d00
commit 6b1e7726e7
5 changed files with 64 additions and 12 deletions

View File

@ -145,7 +145,9 @@ New Features
* SOLR-4717/SOLR-1351: SimpleFacets now work with localParams allowing faceting on the
same field multiple ways (ryan, Uri Boness)
* SOLR-4671: CSVResponseWriter now supports pseudo fields. (ryan, nihed mbarek)
Bug Fixes
----------------------

View File

@ -235,19 +235,27 @@ class CSVWriter extends TextResponseWriter {
// encapsulator will already be disabled if it wasn't specified
}
Collection<String> fields = returnFields.getLuceneFieldNames();
Collection<String> fields = returnFields.getRequestedFieldNames();
Object responseObj = rsp.getValues().get("response");
boolean returnOnlyStored = false;
if (fields==null) {
if (fields==null||returnFields.hasPatternMatching()) {
if (responseObj instanceof SolrDocumentList) {
// get the list of fields from the SolrDocumentList
fields = new LinkedHashSet<String>();
if(fields==null) {
fields = new LinkedHashSet<String>();
}
for (SolrDocument sdoc: (SolrDocumentList)responseObj) {
fields.addAll(sdoc.getFieldNames());
}
} else {
// get the list of fields from the index
fields = req.getSearcher().getFieldNames();
Collection<String> all = req.getSearcher().getFieldNames();
if(fields==null) {
fields = all;
}
else {
fields.addAll(all);
}
}
if (returnFields.wantsScore()) {
fields.add("score");

View File

@ -35,6 +35,13 @@ public abstract class ReturnFields {
*/
public abstract Set<String> getLuceneFieldNames();
/**
* The requested field names (includes pseudo fields)
* <p>
* @return Set of field names or <code>null</code> (all fields).
*/
public abstract Set<String> getRequestedFieldNames();
/** Returns <code>true</code> if the specified field should be returned. */
public abstract boolean wantsField(String name);
@ -44,6 +51,9 @@ public abstract class ReturnFields {
/** Returns <code>true</code> if the score should be returned. */
public abstract boolean wantsScore();
/** Returns <code>true</code> if the fieldnames should be picked with a pattern */
public abstract boolean hasPatternMatching();
/** Returns the DocTransformer used to modify documents, or <code>null</code> */
public abstract DocTransformer getTransformer();
}

View File

@ -52,14 +52,14 @@ public class SolrReturnFields extends ReturnFields {
private final List<String> globs = new ArrayList<String>(1);
// The lucene field names to request from the SolrIndexSearcher
// Order is important for CSVResponseWriter
private final Set<String> fields = new LinkedHashSet<String>();
private final Set<String> fields = new HashSet<String>();
// Field names that are OK to include in the response.
// This will include pseudo fields, lucene fields, and matching globs
private Set<String> okFieldNames = new HashSet<String>();
// The list of explicitly requested fields
// Order is important for CSVResponseWriter
private Set<String> reqFieldNames = null;
protected DocTransformer transformer;
@ -122,7 +122,7 @@ public class SolrReturnFields extends ReturnFields {
if(from.equals(rename.getName(j))) {
rename.setName(j, to); // copy from the current target
if(reqFieldNames==null) {
reqFieldNames = new HashSet<String>();
reqFieldNames = new LinkedHashSet<String>();
}
reqFieldNames.add(to); // don't rename our current target
}
@ -360,12 +360,16 @@ public class SolrReturnFields extends ReturnFields {
private void addField(String field, String key, DocTransformers augmenters, SolrQueryRequest req)
{
if(reqFieldNames==null) {
reqFieldNames = new LinkedHashSet<String>();
}
if(key==null) {
if(reqFieldNames==null) {
reqFieldNames = new HashSet<String>();
}
reqFieldNames.add(field);
}
else {
reqFieldNames.add(key);
}
fields.add(field); // need to put in the map to maintain order for things like CSVResponseWriter
okFieldNames.add( field );
@ -385,6 +389,19 @@ public class SolrReturnFields extends ReturnFields {
return (_wantsAllFields || fields.isEmpty()) ? null : fields;
}
@Override
public Set<String> getRequestedFieldNames() {
if(_wantsAllFields || reqFieldNames==null || reqFieldNames.isEmpty()) {
return null;
}
return reqFieldNames;
}
@Override
public boolean hasPatternMatching() {
return !globs.isEmpty();
}
@Override
public boolean wantsField(String name)
{

View File

@ -59,7 +59,7 @@ public class TestCSVResponseWriter extends SolrTestCaseJ4 {
// test multivalued
assertEquals("2,\"hi,there\"\n"
, h.query(req("q","id:2", "wt","csv", "csv.header","false", "fl","id,v_ss")));
// test separator change
assertEquals("2|\"hi|there\"\n"
, h.query(req("q","id:2", "wt","csv", "csv.header","false", "csv.separator","|", "fl","id,v_ss")));
@ -193,6 +193,21 @@ public class TestCSVResponseWriter extends SolrTestCaseJ4 {
req.close();
}
@Test
public void testPseudoFields() throws Exception {
// Use Pseudo Field
assertEquals("1,hi",
h.query(req("q","id:1", "wt","csv", "csv.header","false", "fl","XXX:id,foo_s")).trim());
String txt = h.query(req("q","id:1", "wt","csv", "csv.header","true", "fl","XXX:id,YYY:[docid],FOO:foo_s"));
String[] lines = txt.split("\n");
assertEquals(2, lines.length);
assertEquals("XXX,YYY,FOO", lines[0] );
assertEquals("1,0,hi", lines[1] );
}
/*
* Utility method to sort a comma separated list of strings, for easier comparison regardless of platform