org.apache.solr.search.ReturnFields Java Examples

The following examples show how to use org.apache.solr.search.ReturnFields. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MergeSearchComponent.java    From BioSolr with Apache License 2.0 5 votes vote down vote up
@Override
public void modifyRequest(ResponseBuilder rb, SearchComponent who, ShardRequest sreq) {
  // do the filterQParser stuff first
  super.modifyRequest(rb, who, sreq);
  
  if (! doMerge(rb)) {
    return;
  }
  
  ReturnFields rf = rb.rsp.getReturnFields();
  if (rf.wantsAllFields()) {
    // we already have what we need since we ask for everything...
    return;
  }

  IndexSchema schema = rb.req.getCore().getLatestSchema();
  for (SchemaField field : schema.getFields().values()) {
    if (! rf.wantsField(field.getName())) {
      continue;
    }
    for (String source : schema.getCopySources(field.getName())) {
      if (rf.wantsField(source)) {
        continue;
      }
      sreq.params.add(CommonParams.FL, source);
    }
  }
}
 
Example #2
Source File: TestSolrQueryResponse.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
@Test
public void testReturnFields() throws Exception {
  final SolrQueryResponse response = new SolrQueryResponse();
  final ReturnFields defaultReturnFields = new SolrReturnFields();
  assertEquals("returnFields initial value", defaultReturnFields.toString(), response.getReturnFields().toString());
  final SolrReturnFields newValue = new SolrReturnFields((random().nextBoolean()
      ? SolrReturnFields.SCORE : "value"), null);
  response.setReturnFields(newValue);
  assertEquals("returnFields new value", newValue.toString(), response.getReturnFields().toString());
}
 
Example #3
Source File: BasicResultContext.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
public BasicResultContext(DocList docList, ReturnFields returnFields, SolrIndexSearcher searcher, Query query, SolrQueryRequest req) {
  assert docList!=null;
  this.docList = docList;
  this.returnFields = returnFields;
  this.searcher = searcher;
  this.query = query;
  this.req = req;
}
 
Example #4
Source File: SolrPluginUtils.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * Pre-fetch documents into the index searcher's document cache.
 *
 * This is an entirely optional step which you might want to perform for
 * the following reasons:
 *
 * <ul>
 *     <li>Locates the document-retrieval costs in one spot, which helps
 *     detailed performance measurement</li>
 *
 *     <li>Determines a priori what fields will be needed to be fetched by
 *     various subtasks, like response writing and highlighting.  This
 *     minimizes the chance that many needed fields will be loaded lazily.
 *     (it is more efficient to load all the field we require normally).</li>
 * </ul>
 *
 * If lazy field loading is disabled, this method does nothing.
 */
public static void optimizePreFetchDocs(ResponseBuilder rb,
                                        DocList docs,
                                        Query query,
                                        SolrQueryRequest req,
                                        SolrQueryResponse res) throws IOException {
  SolrIndexSearcher searcher = req.getSearcher();
  if(!searcher.getDocFetcher().isLazyFieldLoadingEnabled()) {
    // nothing to do
    return;
  }

  ReturnFields returnFields = res.getReturnFields();
  if(returnFields.getLuceneFieldNames() != null) {
    Set<String> fieldFilter = returnFields.getLuceneFieldNames();

    if (rb.doHighlights) {
      // copy return fields list
      fieldFilter = new HashSet<>(fieldFilter);
      // add highlight fields

      SolrHighlighter highlighter = HighlightComponent.getHighlighter(req.getCore());
      for (String field: highlighter.getHighlightFields(query, req, null))
        fieldFilter.add(field);

      // fetch unique key if one exists.
      SchemaField keyField = searcher.getSchema().getUniqueKeyField();
      if(null != keyField)
        fieldFilter.add(keyField.getName());
    }

    // get documents
    DocIterator iter = docs.iterator();
    for (int i=0; i<docs.size(); i++) {
      searcher.doc(iter.nextDoc(), fieldFilter);
    }

  }

}
 
Example #5
Source File: XMLWriter.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
/**
 * The SolrDocument should already have multivalued fields implemented as
 * Collections -- this will not rewrite to &lt;arr&gt;
 */
@Override
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx ) throws IOException {
  startTag("doc", name, false);
  incLevel();

  for (String fname : doc.getFieldNames()) {
    if (returnFields!= null && !returnFields.wantsField(fname)) {
      continue;
    }

    Object val = doc.getFieldValue(fname);
    if( "_explain_".equals( fname ) ) {
      if (log.isDebugEnabled()) {
        log.debug(String.valueOf(val));
      }
    }
    writeVal(fname, val);
  }

  if(doc.hasChildDocuments()) {
    for(SolrDocument childDoc : doc.getChildDocuments()) {
      writeSolrDocument(null, childDoc, new SolrReturnFields(), idx);
    }
  }

  decLevel();
  writer.write("</doc>");
}
 
Example #6
Source File: TextResponseWriter.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
public final void writeSolrDocumentList(String name, SolrDocumentList docs, ReturnFields fields) throws IOException
{
  writeStartDocumentList(name, docs.getStart(), docs.size(), docs.getNumFound(), docs.getMaxScore(), docs.getNumFoundExact());
  for( int i=0; i<docs.size(); i++ ) {
    writeSolrDocument( null, docs.get(i), fields, i );
  }
  writeEndDocumentList();
}
 
Example #7
Source File: DocsStreamer.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
/**
 * Converts the specified <code>Document</code> into a <code>SolrDocument</code>.
 * <p>
 * The use of {@link ReturnFields} can be important even when it was already used to retrieve the 
 * {@link Document} from {@link SolrDocumentFetcher} because the Document may have been cached with 
 * more fields then are desired.
 * </p>
 * 
 * @param doc <code>Document</code> to be converted, must not be null
 * @param schema <code>IndexSchema</code> containing the field/fieldType details for the index
 *               the <code>Document</code> came from, must not be null.
 * @param fields <code>ReturnFields</code> instance that can be use to limit the set of fields 
 *               that will be converted, must not be null
 */
public static SolrDocument convertLuceneDocToSolrDoc(Document doc,
                                                     final IndexSchema schema,
                                                     final ReturnFields fields) {
  // TODO move to SolrDocumentFetcher ?  Refactor to also call docFetcher.decorateDocValueFields(...) ?
  assert null != doc;
  assert null != schema;
  assert null != fields;
  
  // can't just use fields.wantsField(String)
  // because that doesn't include extra fields needed by transformers
  final Set<String> fieldNamesNeeded = fields.getLuceneFieldNames();

  BinaryResponseWriter.MaskCharSeqSolrDocument masked = null;
  final SolrDocument out = ResultContext.READASBYTES.get() == null ?
      new SolrDocument() :
      (masked = new BinaryResponseWriter.MaskCharSeqSolrDocument());

  // NOTE: it would be tempting to try and optimize this to loop over fieldNamesNeeded
  // when it's smaller then the IndexableField[] in the Document -- but that's actually *less* effecient
  // since Document.getFields(String) does a full (internal) iteration over the full IndexableField[]
  // see SOLR-11891
  for (IndexableField f : doc.getFields()) {
    final String fname = f.name();
    if (null == fieldNamesNeeded || fieldNamesNeeded.contains(fname) ) {
      // Make sure multivalued fields are represented as lists
      Object existing = masked == null ? out.get(fname) : masked.getRaw(fname);
      if (existing == null) {
        SchemaField sf = schema.getFieldOrNull(fname);
        if (sf != null && sf.multiValued()) {
          List<Object> vals = new ArrayList<>();
          vals.add(f);
          out.setField(fname, vals);
        } else {
          out.setField(fname, f);
        }
      } else {
        out.addField(fname, f);
      }
    }
  }
  return out;
}
 
Example #8
Source File: JSONWriterTest.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Test
public void testJSONSolrDocument() throws Exception {
  SolrQueryRequest req = req(CommonParams.WT,"json",
                             CommonParams.FL,"id,score,_children_,path");
  SolrQueryResponse rsp = new SolrQueryResponse();
  JSONResponseWriter w = new JSONResponseWriter();

  ReturnFields returnFields = new SolrReturnFields(req);
  rsp.setReturnFields(returnFields);

  StringWriter buf = new StringWriter();

  SolrDocument childDoc = new SolrDocument();
  childDoc.addField("id", "2");
  childDoc.addField("score", "0.4");
  childDoc.addField("path", Arrays.asList("a>b", "a>b>c"));

  SolrDocumentList childList = new SolrDocumentList();
  childList.setNumFound(1);
  childList.setStart(0);
  childList.add(childDoc);

  SolrDocument solrDoc = new SolrDocument();
  solrDoc.addField("id", "1");
  solrDoc.addField("subject", "hello2");
  solrDoc.addField("title", "hello3");
  solrDoc.addField("score", "0.7");
  solrDoc.setField("_children_", childList);

  SolrDocumentList list = new SolrDocumentList();
  list.setNumFound(1);
  list.setStart(0);
  list.setMaxScore(0.7f);
  list.add(solrDoc);

  rsp.addResponse(list);

  w.write(buf, req, rsp);
  String result = buf.toString();
  assertFalse("response contains unexpected fields: " + result, 
              result.contains("hello") || 
              result.contains("\"subject\"") || 
              result.contains("\"title\""));
  assertTrue("response doesn't contain expected fields: " + result, 
             result.contains("\"id\"") &&
             result.contains("\"score\"") && result.contains("_children_"));

  String expectedResult = "{'response':{'numFound':1,'start':0,'maxScore':0.7, 'numFoundExact':true,'docs':[{'id':'1', 'score':'0.7'," +
      " '_children_':{'numFound':1,'start':0,'numFoundExact':true,'docs':[{'id':'2', 'score':'0.4', 'path':['a>b', 'a>b>c']}] }}] }}";
  String error = JSONTestUtil.match(result, "=="+expectedResult);
  assertNull("response validation failed with error: " + error, error);

  req.close();
}
 
Example #9
Source File: RealTimeGetComponent.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
public ReturnFields getReturnFields() {
  return this.returnFields;
}
 
Example #10
Source File: RealTimeGetComponent.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
public RTGResultContext(ReturnFields returnFields, SolrIndexSearcher searcher, SolrQueryRequest req) {
  this.returnFields = returnFields;
  this.searcher = searcher;
  this.req = req;
}
 
Example #11
Source File: RealTimeGetComponent.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
/***
 * Given a partial document obtained from the transaction log (e.g. as a result of RTG), resolve to a full document
 * by populating all the partial updates that were applied on top of that last full document update.
 * 
 * @param onlyTheseFields When a non-null set of field names is passed in, the resolve process only attempts to populate
 *        the given fields in this set. When this set is null, it resolves all fields.
 * @return Returns the merged document, i.e. the resolved full document, or null if the document was not found (deleted
 *          after the resolving began)
 */
private static SolrDocument resolveFullDocument(SolrCore core, BytesRef idBytes,
                                                ReturnFields returnFields, SolrInputDocument partialDoc,
                                                @SuppressWarnings({"rawtypes"}) List logEntry,
                                                Set<String> onlyTheseFields) throws IOException {
  if (idBytes == null || (logEntry.size() != 5 && logEntry.size() != 6)) {
    throw new SolrException(ErrorCode.INVALID_STATE, "Either Id field not present in partial document or log entry doesn't have previous version.");
  }
  long prevPointer = (long) logEntry.get(UpdateLog.PREV_POINTER_IDX);
  long prevVersion = (long) logEntry.get(UpdateLog.PREV_VERSION_IDX);

  // get the last full document from ulog
  UpdateLog ulog = core.getUpdateHandler().getUpdateLog();
  long lastPrevPointer = ulog.applyPartialUpdates(idBytes, prevPointer, prevVersion, onlyTheseFields, partialDoc);

  if (lastPrevPointer == -1) { // full document was not found in tlog, but exists in index
    SolrDocument mergedDoc = mergePartialDocWithFullDocFromIndex(core, idBytes, returnFields, onlyTheseFields, partialDoc);
    return mergedDoc;
  } else if (lastPrevPointer > 0) {
    // We were supposed to have found the last full doc also in the tlogs, but the prevPointer links led to nowhere
    // We should reopen a new RT searcher and get the doc. This should be a rare occurrence
    Term idTerm = new Term(core.getLatestSchema().getUniqueKeyField().getName(), idBytes);
    SolrDocument mergedDoc = reopenRealtimeSearcherAndGet(core, idTerm, returnFields);
    if (mergedDoc == null) {
      return null; // the document may have been deleted as the resolving was going on.
    }
    return mergedDoc;
  } else { // i.e. lastPrevPointer==0
    assert lastPrevPointer == 0;
    // We have successfully resolved the document based off the tlogs

    // determine whether we can use the in place document, if the caller specified onlyTheseFields
    // and those fields are all supported for in-place updates
    IndexSchema schema = core.getLatestSchema();
    boolean forInPlaceUpdate = onlyTheseFields != null
        && onlyTheseFields.stream().map(schema::getField)
        .allMatch(f -> null!=f && AtomicUpdateDocumentMerger.isSupportedFieldForInPlaceUpdate(f));

    return toSolrDoc(partialDoc, schema, forInPlaceUpdate);
  }
}
 
Example #12
Source File: RealTimeGetComponent.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public void prepare(ResponseBuilder rb) throws IOException {
  // Set field flags
  ReturnFields returnFields = new SolrReturnFields( rb.req );
  rb.rsp.setReturnFields( returnFields );
}
 
Example #13
Source File: QueryComponent.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
protected void createMainQuery(ResponseBuilder rb) {
  ShardRequest sreq = new ShardRequest();
  sreq.purpose = ShardRequest.PURPOSE_GET_TOP_IDS;

  String keyFieldName = rb.req.getSchema().getUniqueKeyField().getName();

  // one-pass algorithm if only id and score fields are requested, but not if fl=score since that's the same as fl=*,score
  ReturnFields fields = rb.rsp.getReturnFields();

  // distrib.singlePass=true forces a one-pass query regardless of requested fields
  boolean distribSinglePass = rb.req.getParams().getBool(ShardParams.DISTRIB_SINGLE_PASS, false);

  if(distribSinglePass || (fields != null && fields.wantsField(keyFieldName)
      && fields.getRequestedFieldNames() != null  
      && (!fields.hasPatternMatching() && Arrays.asList(keyFieldName, "score").containsAll(fields.getRequestedFieldNames())))) {
    sreq.purpose |= ShardRequest.PURPOSE_GET_FIELDS;
    rb.onePassDistributedQuery = true;
  }

  sreq.params = new ModifiableSolrParams(rb.req.getParams());
  // TODO: base on current params or original params?

  // don't pass through any shards param
  sreq.params.remove(ShardParams.SHARDS);

  // set the start (offset) to 0 for each shard request so we can properly merge
  // results from the start.
  if(rb.shards_start > -1) {
    // if the client set shards.start set this explicitly
    sreq.params.set(CommonParams.START,rb.shards_start);
  } else {
    sreq.params.set(CommonParams.START, "0");
  }
  // TODO: should we even use the SortSpec?  That's obtained from the QParser, and
  // perhaps we shouldn't attempt to parse the query at this level?
  // Alternate Idea: instead of specifying all these things at the upper level,
  // we could just specify that this is a shard request.
  if(rb.shards_rows > -1) {
    // if the client set shards.rows set this explicity
    sreq.params.set(CommonParams.ROWS,rb.shards_rows);
  } else {
    // what if rows<0 as it is allowed for grouped request??
    sreq.params.set(CommonParams.ROWS, rb.getSortSpec().getOffset() + rb.getSortSpec().getCount());
  }

  sreq.params.set(ResponseBuilder.FIELD_SORT_VALUES,"true");

  boolean shardQueryIncludeScore = (rb.getFieldFlags() & SolrIndexSearcher.GET_SCORES) != 0 || rb.getSortSpec().includesScore();
  StringBuilder additionalFL = new StringBuilder();
  boolean additionalAdded = false;
  if (distribSinglePass)  {
    String[] fls = rb.req.getParams().getParams(CommonParams.FL);
    if (fls != null && fls.length > 0 && (fls.length != 1 || !fls[0].isEmpty())) {
      // If the outer request contains actual FL's use them...
      sreq.params.set(CommonParams.FL, fls);
      if (!fields.wantsField(keyFieldName))  {
        additionalAdded = addFL(additionalFL, keyFieldName, additionalAdded);
      }
    } else {
      // ... else we need to explicitly ask for all fields, because we are going to add
      // additional fields below
      sreq.params.set(CommonParams.FL, "*");
    }
    if (!fields.wantsScore() && shardQueryIncludeScore) {
      additionalAdded = addFL(additionalFL, "score", additionalAdded);
    }
  } else {
    // reset so that only unique key is requested in shard requests
    sreq.params.set(CommonParams.FL, rb.req.getSchema().getUniqueKeyField().getName());
    if (shardQueryIncludeScore) {
      additionalAdded = addFL(additionalFL, "score", additionalAdded);
    }
  }

  // TODO: should this really sendGlobalDfs if just includeScore?

  if (shardQueryIncludeScore || rb.isDebug()) {
    StatsCache statsCache = rb.req.getSearcher().getStatsCache();
    sreq.purpose |= ShardRequest.PURPOSE_SET_TERM_STATS;
    statsCache.sendGlobalStats(rb, sreq);
  }

  if (additionalAdded) sreq.params.add(CommonParams.FL, additionalFL.toString());

  rb.addRequest(this, sreq);
}
 
Example #14
Source File: GeoJSONResponseWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
  if( idx > 0 ) {
    writeArraySeparator();
  }

  indent();
  writeMapOpener(-1); 
  incLevel();

  writeKey("type", false);
  writeVal(null, "Feature");
  
  Object val = doc.getFieldValue(geofield);
  if(val != null) {  
    writeFeatureGeometry(val);
  }
  
  boolean first=true;
  for (String fname : doc.getFieldNames()) {
    if (fname.equals(geofield) || ((returnFields!= null && !returnFields.wantsField(fname)))) {
      continue;
    }
    writeMapSeparator();
    if (first) {
      indent();
      writeKey("properties", false);
      writeMapOpener(-1); 
      incLevel();
      
      first=false;
    }

    indent();
    writeKey(fname, true);
    val = doc.getFieldValue(fname);
    writeVal(fname, val);
  }

  // GeoJSON does not really support nested FeatureCollections
  if(doc.hasChildDocuments()) {
    if(first == false) {
      writeMapSeparator();
      indent();
    }
    writeKey("_childDocuments_", true);
    writeArrayOpener(doc.getChildDocumentCount());
    List<SolrDocument> childDocs = doc.getChildDocuments();
    for(int i=0; i<childDocs.size(); i++) {
      writeSolrDocument(null, childDocs.get(i), null, i);
    }
    writeArrayCloser();
  }

  // check that we added any properties
  if(!first) {
    decLevel();
    writeMapCloser();
  }
  
  decLevel();
  writeMapCloser();
}
 
Example #15
Source File: BinaryResponseWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
    public Object resolve(Object o, JavaBinCodec codec) throws IOException {
      if (o instanceof StoredField) {
        CharSequence val = ((StoredField) o).getCharSequenceValue();
        if (val instanceof Utf8CharSequence) {
          codec.writeUTF8Str((Utf8CharSequence) val);
          return null;
        }
      }
      if (o instanceof ResultContext) {
        ReturnFields orig = returnFields;
        ResultContext res = (ResultContext)o;
        if(res.getReturnFields()!=null) {
          returnFields = res.getReturnFields();
        }
//        if (useUtf8CharSeq) {
        ResultContext.READASBYTES.set(fieldName -> {
          SchemaField fld = res.getRequest().getSchema().getFieldOrNull(fieldName);
          return fld != null && fld.getType().isUtf8Field();
        });

        try {
          writeResults(res, codec);
        } finally {
          ResultContext.READASBYTES.remove();
        }
        returnFields = orig;

        return null; // null means we completely handled it
      }
      if (o instanceof DocList) {
        ResultContext ctx = new BasicResultContext((DocList)o, returnFields, null, null, solrQueryRequest);
        writeResults(ctx, codec);
        return null; // null means we completely handled it
      }
      if( o instanceof IndexableField ) {
        if(schema == null) schema = solrQueryRequest.getSchema();

        IndexableField f = (IndexableField)o;
        SchemaField sf = schema.getFieldOrNull(f.name());
        try {
          o = DocsStreamer.getValue(sf, f);
        } catch (Exception e) {
          log.warn("Error reading a field : {}", o, e);
        }
      }
      return o;
    }
 
Example #16
Source File: BinaryResponseWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
public Resolver(SolrQueryRequest req, ReturnFields returnFields) {
  solrQueryRequest = req;
  this.returnFields = returnFields;
}
 
Example #17
Source File: SchemaXmlWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
  // no-op
}
 
Example #18
Source File: BasicResultContext.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public ReturnFields getReturnFields() {
  return returnFields;
}
 
Example #19
Source File: SubQueryAugmenterFactory.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public ReturnFields getReturnFields() {
  return justWantAllFields;
}
 
Example #20
Source File: JSONResponseWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
  ifNeededWriteTypeAndValueKey("doc");
  super.writeSolrDocument(name, doc, returnFields, idx);
}
 
Example #21
Source File: JSONWriter.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@Override
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
  if( idx > 0 ) {
    writeArraySeparator();
  }

  indent();
  writeMapOpener(doc.size());
  incLevel();

  boolean first=true;
  for (String fname : doc.getFieldNames()) {
    if (returnFields!= null && !returnFields.wantsField(fname)) {
      continue;
    }

    if (first) {
      first=false;
    }
    else {
      writeMapSeparator();
    }

    indent();
    writeKey(fname, true);
    Object val = doc.getFieldValue(fname);
    writeVal(fname, val);
  }

  if(doc.hasChildDocuments()) {
    if(first == false) {
      writeMapSeparator();
      indent();
    }
    writeKey("_childDocuments_", true);
    writeArrayOpener(doc.getChildDocumentCount());
    List<SolrDocument> childDocs = doc.getChildDocuments();
    for(int i=0; i<childDocs.size(); i++) {
      writeSolrDocument(null, childDocs.get(i), null, i);
    }
    writeArrayCloser();
  }

  decLevel();
  writeMapCloser();
}
 
Example #22
Source File: SolrQueryResponse.java    From lucene-solr with Apache License 2.0 2 votes vote down vote up
/**
 * Sets the document field names of fields to return by default when
 * returning DocLists
 */
public void setReturnFields(ReturnFields fields) {
  returnFields=fields;
}
 
Example #23
Source File: TextResponseWriter.java    From lucene-solr with Apache License 2.0 votes vote down vote up
public abstract void writeSolrDocument(String name, SolrDocument doc, ReturnFields fields, int idx) throws IOException; 
Example #24
Source File: ResultContext.java    From lucene-solr with Apache License 2.0 votes vote down vote up
public abstract ReturnFields getReturnFields();