mirror of https://github.com/apache/lucene.git
SOLR-4226: Extract fl parsing code out of ReturnFields constructor
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1429935 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2d1c5560d5
commit
04c86005cc
|
@ -558,6 +558,9 @@ Other Changes
|
|||
* SOLR-4254: Harden the 'leader requests replica to recover' code path.
|
||||
(Mark Miller, yonik)
|
||||
|
||||
* SOLR-4226: Extract fl parsing code out of ReturnFields constructor.
|
||||
(Ryan Ernst via Robert Muir)
|
||||
|
||||
================== 4.0.0 ==================
|
||||
|
||||
Versions of Major Components
|
||||
|
|
|
@ -76,7 +76,7 @@ public class MoreLikeThisHandler extends RequestHandlerBase
|
|||
SolrParams params = req.getParams();
|
||||
|
||||
// Set field flags
|
||||
ReturnFields returnFields = new ReturnFields( req );
|
||||
ReturnFields returnFields = new SolrReturnFields( req );
|
||||
rsp.setReturnFields( returnFields );
|
||||
int flags = 0;
|
||||
if (returnFields.wantsScore()) {
|
||||
|
|
|
@ -93,7 +93,7 @@ public class QueryComponent extends SearchComponent
|
|||
SolrQueryResponse rsp = rb.rsp;
|
||||
|
||||
// Set field flags
|
||||
ReturnFields returnFields = new ReturnFields( req );
|
||||
ReturnFields returnFields = new SolrReturnFields( req );
|
||||
rsp.setReturnFields( returnFields );
|
||||
int flags = 0;
|
||||
if (returnFields.wantsScore()) {
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.apache.solr.schema.IndexSchema;
|
|||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.search.ReturnFields;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
import org.apache.solr.update.DocumentBuilder;
|
||||
import org.apache.solr.update.PeerSync;
|
||||
import org.apache.solr.update.UpdateLog;
|
||||
|
@ -72,7 +73,7 @@ public class RealTimeGetComponent extends SearchComponent
|
|||
@Override
|
||||
public void prepare(ResponseBuilder rb) throws IOException {
|
||||
// Set field flags
|
||||
ReturnFields returnFields = new ReturnFields( rb.req );
|
||||
ReturnFields returnFields = new SolrReturnFields( rb.req );
|
||||
rb.rsp.setReturnFields( returnFields );
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.apache.solr.search.ReturnFields;
|
|||
import org.apache.solr.search.DocList;
|
||||
import org.apache.solr.search.DocListAndSet;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
import org.apache.solr.util.SolrPluginUtils;
|
||||
import org.apache.solr.util.plugin.SolrCoreAware;
|
||||
|
||||
|
@ -111,7 +112,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar
|
|||
(1 == fldLst.length && 0 == fldLst[0].length())) {
|
||||
|
||||
// no tv.fl, parse the main fl
|
||||
ReturnFields rf = new ReturnFields
|
||||
ReturnFields rf = new SolrReturnFields
|
||||
(params.getParams(CommonParams.FL), rb.req);
|
||||
|
||||
if (rf.wantsAllFields()) {
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.apache.solr.response;
|
|||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.search.ReturnFields;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -123,7 +124,7 @@ public class SolrQueryResponse {
|
|||
*/
|
||||
public ReturnFields getReturnFields() {
|
||||
if( returnFields == null ) {
|
||||
returnFields = new ReturnFields(); // by default return everything
|
||||
returnFields = new SolrReturnFields(); // by default return everything
|
||||
}
|
||||
return returnFields;
|
||||
}
|
||||
|
|
|
@ -18,25 +18,7 @@ package org.apache.solr.search;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.lucene.queries.function.FunctionQuery;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.valuesource.QueryValueSource;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.params.MapSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
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.RenameFieldTransformer;
|
||||
import org.apache.solr.response.transform.ScoreAugmenter;
|
||||
import org.apache.solr.response.transform.TransformerFactory;
|
||||
import org.apache.solr.response.transform.ValueSourceAugmenter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A class representing the return fields
|
||||
|
@ -44,376 +26,24 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* @since solr 4.0
|
||||
*/
|
||||
public class ReturnFields
|
||||
{
|
||||
static final Logger log = LoggerFactory.getLogger( ReturnFields.class );
|
||||
public abstract class ReturnFields {
|
||||
/**
|
||||
* Set of field names with their exact names from the lucene index.
|
||||
* <p>
|
||||
* Class such as ResponseWriters pass this to {@link SolrIndexSearcher#doc(int, Set)}.
|
||||
* @return Set of field names or <code>null</code> (all fields).
|
||||
*/
|
||||
public abstract Set<String> getLuceneFieldNames();
|
||||
|
||||
// Special Field Keys
|
||||
public static final String SCORE = "score";
|
||||
/** Returns <code>true</code> if the specified field should be returned. */
|
||||
public abstract boolean wantsField(String name);
|
||||
|
||||
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>();
|
||||
|
||||
// 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>();
|
||||
/** Returns <code>true</code> if all fields should be returned. */
|
||||
public abstract boolean wantsAllFields();
|
||||
|
||||
// The list of explicitly requested fields
|
||||
private Set<String> reqFieldNames = null;
|
||||
|
||||
private DocTransformer transformer;
|
||||
private boolean _wantsScore = false;
|
||||
private boolean _wantsAllFields = false;
|
||||
/** Returns <code>true</code> if the score should be returned. */
|
||||
public abstract boolean wantsScore();
|
||||
|
||||
public ReturnFields() {
|
||||
_wantsAllFields = true;
|
||||
}
|
||||
|
||||
public ReturnFields(SolrQueryRequest req) {
|
||||
this( req.getParams().getParams(CommonParams.FL), req );
|
||||
}
|
||||
|
||||
public ReturnFields(String fl, SolrQueryRequest req) {
|
||||
// this( (fl==null)?null:SolrPluginUtils.split(fl), req );
|
||||
if( fl == null ) {
|
||||
parseFieldList((String[])null, req);
|
||||
}
|
||||
else {
|
||||
if( fl.trim().length() == 0 ) {
|
||||
// legacy thing to support fl=' ' => fl=*,score!
|
||||
// maybe time to drop support for this?
|
||||
// See ConvertedLegacyTest
|
||||
_wantsScore = true;
|
||||
_wantsAllFields = true;
|
||||
transformer = new ScoreAugmenter(SCORE);
|
||||
}
|
||||
else {
|
||||
parseFieldList( new String[]{fl}, req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ReturnFields(String[] fl, SolrQueryRequest req) {
|
||||
parseFieldList(fl, req);
|
||||
}
|
||||
|
||||
private void parseFieldList(String[] fl, SolrQueryRequest req) {
|
||||
_wantsScore = false;
|
||||
_wantsAllFields = false;
|
||||
if (fl == null || fl.length == 0 || fl.length == 1 && fl[0].length()==0) {
|
||||
_wantsAllFields = true;
|
||||
return;
|
||||
}
|
||||
|
||||
NamedList<String> rename = new NamedList<String>();
|
||||
DocTransformers augmenters = new DocTransformers();
|
||||
for (String fieldList : fl) {
|
||||
add(fieldList,rename,augmenters,req);
|
||||
}
|
||||
for( int i=0; i<rename.size(); 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>();
|
||||
}
|
||||
reqFieldNames.add(to); // don't rename our current target
|
||||
}
|
||||
}
|
||||
}
|
||||
augmenters.addTransformer( new RenameFieldTransformer( from, to, copy ) );
|
||||
}
|
||||
|
||||
if( !_wantsAllFields ) {
|
||||
if( !globs.isEmpty() ) {
|
||||
// TODO??? need to fill up the fields with matching field names in the index
|
||||
// and add them to okFieldNames?
|
||||
// maybe just get all fields?
|
||||
// this would disable field selection optimization... i think thatis OK
|
||||
fields.clear(); // this will get all fields, and use wantsField to limit
|
||||
}
|
||||
okFieldNames.addAll( fields );
|
||||
}
|
||||
|
||||
if( augmenters.size() == 1 ) {
|
||||
transformer = augmenters.getTransformer(0);
|
||||
}
|
||||
else if( augmenters.size() > 1 ) {
|
||||
transformer = augmenters;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// like getId, but also accepts dashes for legacy fields
|
||||
String getFieldName(QueryParsing.StrParser sp) {
|
||||
sp.eatws();
|
||||
int id_start = sp.pos;
|
||||
char ch;
|
||||
if (sp.pos < sp.end && (ch = sp.val.charAt(sp.pos)) != '$' && Character.isJavaIdentifierStart(ch)) {
|
||||
sp.pos++;
|
||||
while (sp.pos < sp.end) {
|
||||
ch = sp.val.charAt(sp.pos);
|
||||
if (!Character.isJavaIdentifierPart(ch) && ch != '.' && ch != '-') {
|
||||
break;
|
||||
}
|
||||
sp.pos++;
|
||||
}
|
||||
return sp.val.substring(id_start, sp.pos);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void add(String fl, NamedList<String> rename, DocTransformers augmenters, SolrQueryRequest req) {
|
||||
if( fl == null ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
QueryParsing.StrParser sp = new QueryParsing.StrParser(fl);
|
||||
|
||||
for(;;) {
|
||||
sp.opt(',');
|
||||
sp.eatws();
|
||||
if (sp.pos >= sp.end) break;
|
||||
|
||||
int start = sp.pos;
|
||||
|
||||
// short circuit test for a really simple field name
|
||||
String key = null;
|
||||
String field = getFieldName(sp);
|
||||
char ch = sp.ch();
|
||||
|
||||
if (field != null) {
|
||||
if (sp.opt(':')) {
|
||||
// this was a key, not a field name
|
||||
key = field;
|
||||
field = null;
|
||||
sp.eatws();
|
||||
start = sp.pos;
|
||||
} else {
|
||||
if (Character.isWhitespace(ch) || ch == ',' || ch==0) {
|
||||
addField( field, key, augmenters, req );
|
||||
continue;
|
||||
}
|
||||
// an invalid field name... reset the position pointer to retry
|
||||
sp.pos = start;
|
||||
field = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
// we read "key : "
|
||||
field = sp.getId(null);
|
||||
ch = sp.ch();
|
||||
if (field != null && (Character.isWhitespace(ch) || ch == ',' || ch==0)) {
|
||||
rename.add(field, key);
|
||||
addField( field, key, augmenters, req );
|
||||
continue;
|
||||
}
|
||||
// an invalid field name... reset the position pointer to retry
|
||||
sp.pos = start;
|
||||
field = null;
|
||||
}
|
||||
|
||||
if (field == null) {
|
||||
// We didn't find a simple name, so let's see if it's a globbed field name.
|
||||
// Globbing only works with field names of the recommended form (roughly like java identifiers)
|
||||
|
||||
field = sp.getGlobbedId(null);
|
||||
ch = sp.ch();
|
||||
if (field != null && (Character.isWhitespace(ch) || ch == ',' || ch==0)) {
|
||||
// "*" looks and acts like a glob, but we give it special treatment
|
||||
if ("*".equals(field)) {
|
||||
_wantsAllFields = true;
|
||||
} else {
|
||||
globs.add(field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// an invalid glob
|
||||
sp.pos = start;
|
||||
}
|
||||
|
||||
String funcStr = sp.val.substring(start);
|
||||
|
||||
// Is it an augmenter of the form [augmenter_name foo=1 bar=myfield]?
|
||||
// This is identical to localParams syntax except it uses [] instead of {!}
|
||||
|
||||
if (funcStr.startsWith("[")) {
|
||||
Map<String,String> augmenterArgs = new HashMap<String,String>();
|
||||
int end = QueryParsing.parseLocalParams(funcStr, 0, augmenterArgs, req.getParams(), "[", ']');
|
||||
sp.pos += end;
|
||||
|
||||
// [foo] is short for [type=foo] in localParams syntax
|
||||
String augmenterName = augmenterArgs.remove("type");
|
||||
String disp = key;
|
||||
if( disp == null ) {
|
||||
disp = '['+augmenterName+']';
|
||||
}
|
||||
|
||||
TransformerFactory factory = req.getCore().getTransformerFactory( augmenterName );
|
||||
if( factory != null ) {
|
||||
MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs );
|
||||
augmenters.addTransformer( factory.create(disp, augmenterParams, req) );
|
||||
}
|
||||
else {
|
||||
// unknown transformer?
|
||||
}
|
||||
addField(field, disp, augmenters, req);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// let's try it as a function instead
|
||||
QParser parser = QParser.getParser(funcStr, FunctionQParserPlugin.NAME, req);
|
||||
Query q = null;
|
||||
ValueSource vs = null;
|
||||
|
||||
try {
|
||||
if (parser instanceof FunctionQParser) {
|
||||
FunctionQParser fparser = (FunctionQParser)parser;
|
||||
fparser.setParseMultipleSources(false);
|
||||
fparser.setParseToEnd(false);
|
||||
|
||||
q = fparser.getQuery();
|
||||
|
||||
if (fparser.localParams != null) {
|
||||
if (fparser.valFollowedParams) {
|
||||
// need to find the end of the function query via the string parser
|
||||
int leftOver = fparser.sp.end - fparser.sp.pos;
|
||||
sp.pos = sp.end - leftOver; // reset our parser to the same amount of leftover
|
||||
} else {
|
||||
// the value was via the "v" param in localParams, so we need to find
|
||||
// the end of the local params themselves to pick up where we left off
|
||||
sp.pos = start + fparser.localParamsEnd;
|
||||
}
|
||||
} else {
|
||||
// need to find the end of the function query via the string parser
|
||||
int leftOver = fparser.sp.end - fparser.sp.pos;
|
||||
sp.pos = sp.end - leftOver; // reset our parser to the same amount of leftover
|
||||
}
|
||||
} else {
|
||||
// A QParser that's not for function queries.
|
||||
// It must have been specified via local params.
|
||||
q = parser.getQuery();
|
||||
|
||||
assert parser.getLocalParams() != null;
|
||||
sp.pos = start + parser.localParamsEnd;
|
||||
}
|
||||
|
||||
|
||||
if (q instanceof FunctionQuery) {
|
||||
vs = ((FunctionQuery)q).getValueSource();
|
||||
} else {
|
||||
vs = new QueryValueSource(q, 0.0f);
|
||||
}
|
||||
|
||||
if (key==null) {
|
||||
SolrParams localParams = parser.getLocalParams();
|
||||
if (localParams != null) {
|
||||
key = localParams.get("key");
|
||||
}
|
||||
if (key == null) {
|
||||
// use the function name itself as the field name
|
||||
key = sp.val.substring(start, sp.pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (key==null) {
|
||||
key = funcStr;
|
||||
}
|
||||
okFieldNames.add( key );
|
||||
okFieldNames.add( funcStr );
|
||||
augmenters.addTransformer( new ValueSourceAugmenter( key, parser, vs ) );
|
||||
}
|
||||
catch (SyntaxError e) {
|
||||
// try again, simple rules for a field name with no whitespace
|
||||
sp.pos = start;
|
||||
field = sp.getSimpleString();
|
||||
|
||||
if (req.getSchema().getFieldOrNull(field) != null) {
|
||||
// OK, it was an oddly named field
|
||||
fields.add(field);
|
||||
if( key != null ) {
|
||||
rename.add(field, key);
|
||||
}
|
||||
} else {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// end try as function
|
||||
|
||||
} // end for(;;)
|
||||
} catch (SyntaxError e) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addField( String field, String key, DocTransformers augmenters, SolrQueryRequest req )
|
||||
{
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getLuceneFieldNames()
|
||||
{
|
||||
return (_wantsAllFields || fields.isEmpty()) ? null : fields;
|
||||
}
|
||||
|
||||
public boolean wantsAllFields()
|
||||
{
|
||||
return _wantsAllFields;
|
||||
}
|
||||
|
||||
public boolean wantsScore()
|
||||
{
|
||||
return _wantsScore;
|
||||
}
|
||||
|
||||
public boolean wantsField( String name )
|
||||
{
|
||||
if( _wantsAllFields || okFieldNames.contains( name ) ){
|
||||
return true;
|
||||
}
|
||||
for( String s : globs ) {
|
||||
// TODO something better?
|
||||
if( FilenameUtils.wildcardMatch( name, s ) ) {
|
||||
okFieldNames.add(name); // Don't calculate it again
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public DocTransformer getTransformer()
|
||||
{
|
||||
return transformer;
|
||||
}
|
||||
/** Returns the DocTransformer used to modify documents, or <code>null</code> */
|
||||
public abstract DocTransformer getTransformer();
|
||||
}
|
||||
|
|
|
@ -565,8 +565,8 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable,SolrIn
|
|||
|
||||
/**
|
||||
* Retrieve the {@link Document} instance corresponding to the document id.
|
||||
*
|
||||
* Note: The document will have all fields accessable, but if a field
|
||||
* <p>
|
||||
* Note: The document will have all fields accessible, but if a field
|
||||
* filter is provided, only the provided fields will be loaded (the
|
||||
* remainder will be available lazily).
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.lucene.queries.function.FunctionQuery;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.valuesource.QueryValueSource;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.params.MapSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
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.RenameFieldTransformer;
|
||||
import org.apache.solr.response.transform.ScoreAugmenter;
|
||||
import org.apache.solr.response.transform.TransformerFactory;
|
||||
import org.apache.solr.response.transform.ValueSourceAugmenter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The default implementation of return fields parsing for Solr.
|
||||
*/
|
||||
public class SolrReturnFields extends ReturnFields {
|
||||
// Special Field Keys
|
||||
public static final String SCORE = "score";
|
||||
|
||||
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>();
|
||||
|
||||
// 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
|
||||
private Set<String> reqFieldNames = null;
|
||||
|
||||
protected DocTransformer transformer;
|
||||
protected boolean _wantsScore = false;
|
||||
protected boolean _wantsAllFields = false;
|
||||
|
||||
public SolrReturnFields() {
|
||||
_wantsAllFields = true;
|
||||
}
|
||||
|
||||
public SolrReturnFields(SolrQueryRequest req) {
|
||||
this( req.getParams().getParams(CommonParams.FL), req );
|
||||
}
|
||||
|
||||
public SolrReturnFields(String fl, SolrQueryRequest req) {
|
||||
// this( (fl==null)?null:SolrPluginUtils.split(fl), req );
|
||||
if( fl == null ) {
|
||||
parseFieldList((String[])null, req);
|
||||
}
|
||||
else {
|
||||
if( fl.trim().length() == 0 ) {
|
||||
// legacy thing to support fl=' ' => fl=*,score!
|
||||
// maybe time to drop support for this?
|
||||
// See ConvertedLegacyTest
|
||||
_wantsScore = true;
|
||||
_wantsAllFields = true;
|
||||
transformer = new ScoreAugmenter(SCORE);
|
||||
}
|
||||
else {
|
||||
parseFieldList( new String[]{fl}, req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SolrReturnFields(String[] fl, SolrQueryRequest req) {
|
||||
parseFieldList(fl, req);
|
||||
}
|
||||
|
||||
private void parseFieldList(String[] fl, SolrQueryRequest req) {
|
||||
_wantsScore = false;
|
||||
_wantsAllFields = false;
|
||||
if (fl == null || fl.length == 0 || fl.length == 1 && fl[0].length()==0) {
|
||||
_wantsAllFields = true;
|
||||
return;
|
||||
}
|
||||
|
||||
NamedList<String> rename = new NamedList<String>();
|
||||
DocTransformers augmenters = new DocTransformers();
|
||||
for (String fieldList : fl) {
|
||||
add(fieldList,rename,augmenters,req);
|
||||
}
|
||||
for( int i=0; i<rename.size(); 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>();
|
||||
}
|
||||
reqFieldNames.add(to); // don't rename our current target
|
||||
}
|
||||
}
|
||||
}
|
||||
augmenters.addTransformer( new RenameFieldTransformer( from, to, copy ) );
|
||||
}
|
||||
|
||||
if( !_wantsAllFields ) {
|
||||
if( !globs.isEmpty() ) {
|
||||
// TODO??? need to fill up the fields with matching field names in the index
|
||||
// and add them to okFieldNames?
|
||||
// maybe just get all fields?
|
||||
// this would disable field selection optimization... i think thatis OK
|
||||
fields.clear(); // this will get all fields, and use wantsField to limit
|
||||
}
|
||||
okFieldNames.addAll( fields );
|
||||
}
|
||||
|
||||
if( augmenters.size() == 1 ) {
|
||||
transformer = augmenters.getTransformer(0);
|
||||
}
|
||||
else if( augmenters.size() > 1 ) {
|
||||
transformer = augmenters;
|
||||
}
|
||||
}
|
||||
|
||||
// like getId, but also accepts dashes for legacy fields
|
||||
String getFieldName(QueryParsing.StrParser sp) {
|
||||
sp.eatws();
|
||||
int id_start = sp.pos;
|
||||
char ch;
|
||||
if (sp.pos < sp.end && (ch = sp.val.charAt(sp.pos)) != '$' && Character.isJavaIdentifierStart(ch)) {
|
||||
sp.pos++;
|
||||
while (sp.pos < sp.end) {
|
||||
ch = sp.val.charAt(sp.pos);
|
||||
if (!Character.isJavaIdentifierPart(ch) && ch != '.' && ch != '-') {
|
||||
break;
|
||||
}
|
||||
sp.pos++;
|
||||
}
|
||||
return sp.val.substring(id_start, sp.pos);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void add(String fl, NamedList<String> rename, DocTransformers augmenters, SolrQueryRequest req) {
|
||||
if( fl == null ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
QueryParsing.StrParser sp = new QueryParsing.StrParser(fl);
|
||||
|
||||
for(;;) {
|
||||
sp.opt(',');
|
||||
sp.eatws();
|
||||
if (sp.pos >= sp.end) break;
|
||||
|
||||
int start = sp.pos;
|
||||
|
||||
// short circuit test for a really simple field name
|
||||
String key = null;
|
||||
String field = getFieldName(sp);
|
||||
char ch = sp.ch();
|
||||
|
||||
if (field != null) {
|
||||
if (sp.opt(':')) {
|
||||
// this was a key, not a field name
|
||||
key = field;
|
||||
field = null;
|
||||
sp.eatws();
|
||||
start = sp.pos;
|
||||
} else {
|
||||
if (Character.isWhitespace(ch) || ch == ',' || ch==0) {
|
||||
addField( field, key, augmenters, req );
|
||||
continue;
|
||||
}
|
||||
// an invalid field name... reset the position pointer to retry
|
||||
sp.pos = start;
|
||||
field = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (key != null) {
|
||||
// we read "key : "
|
||||
field = sp.getId(null);
|
||||
ch = sp.ch();
|
||||
if (field != null && (Character.isWhitespace(ch) || ch == ',' || ch==0)) {
|
||||
rename.add(field, key);
|
||||
addField( field, key, augmenters, req );
|
||||
continue;
|
||||
}
|
||||
// an invalid field name... reset the position pointer to retry
|
||||
sp.pos = start;
|
||||
field = null;
|
||||
}
|
||||
|
||||
if (field == null) {
|
||||
// We didn't find a simple name, so let's see if it's a globbed field name.
|
||||
// Globbing only works with field names of the recommended form (roughly like java identifiers)
|
||||
|
||||
field = sp.getGlobbedId(null);
|
||||
ch = sp.ch();
|
||||
if (field != null && (Character.isWhitespace(ch) || ch == ',' || ch==0)) {
|
||||
// "*" looks and acts like a glob, but we give it special treatment
|
||||
if ("*".equals(field)) {
|
||||
_wantsAllFields = true;
|
||||
} else {
|
||||
globs.add(field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// an invalid glob
|
||||
sp.pos = start;
|
||||
}
|
||||
|
||||
String funcStr = sp.val.substring(start);
|
||||
|
||||
// Is it an augmenter of the form [augmenter_name foo=1 bar=myfield]?
|
||||
// This is identical to localParams syntax except it uses [] instead of {!}
|
||||
|
||||
if (funcStr.startsWith("[")) {
|
||||
Map<String,String> augmenterArgs = new HashMap<String,String>();
|
||||
int end = QueryParsing.parseLocalParams(funcStr, 0, augmenterArgs, req.getParams(), "[", ']');
|
||||
sp.pos += end;
|
||||
|
||||
// [foo] is short for [type=foo] in localParams syntax
|
||||
String augmenterName = augmenterArgs.remove("type");
|
||||
String disp = key;
|
||||
if( disp == null ) {
|
||||
disp = '['+augmenterName+']';
|
||||
}
|
||||
|
||||
TransformerFactory factory = req.getCore().getTransformerFactory( augmenterName );
|
||||
if( factory != null ) {
|
||||
MapSolrParams augmenterParams = new MapSolrParams( augmenterArgs );
|
||||
augmenters.addTransformer( factory.create(disp, augmenterParams, req) );
|
||||
}
|
||||
else {
|
||||
// unknown transformer?
|
||||
}
|
||||
addField(field, disp, augmenters, req);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// let's try it as a function instead
|
||||
QParser parser = QParser.getParser(funcStr, FunctionQParserPlugin.NAME, req);
|
||||
Query q = null;
|
||||
ValueSource vs = null;
|
||||
|
||||
try {
|
||||
if (parser instanceof FunctionQParser) {
|
||||
FunctionQParser fparser = (FunctionQParser)parser;
|
||||
fparser.setParseMultipleSources(false);
|
||||
fparser.setParseToEnd(false);
|
||||
|
||||
q = fparser.getQuery();
|
||||
|
||||
if (fparser.localParams != null) {
|
||||
if (fparser.valFollowedParams) {
|
||||
// need to find the end of the function query via the string parser
|
||||
int leftOver = fparser.sp.end - fparser.sp.pos;
|
||||
sp.pos = sp.end - leftOver; // reset our parser to the same amount of leftover
|
||||
} else {
|
||||
// the value was via the "v" param in localParams, so we need to find
|
||||
// the end of the local params themselves to pick up where we left off
|
||||
sp.pos = start + fparser.localParamsEnd;
|
||||
}
|
||||
} else {
|
||||
// need to find the end of the function query via the string parser
|
||||
int leftOver = fparser.sp.end - fparser.sp.pos;
|
||||
sp.pos = sp.end - leftOver; // reset our parser to the same amount of leftover
|
||||
}
|
||||
} else {
|
||||
// A QParser that's not for function queries.
|
||||
// It must have been specified via local params.
|
||||
q = parser.getQuery();
|
||||
|
||||
assert parser.getLocalParams() != null;
|
||||
sp.pos = start + parser.localParamsEnd;
|
||||
}
|
||||
|
||||
|
||||
if (q instanceof FunctionQuery) {
|
||||
vs = ((FunctionQuery)q).getValueSource();
|
||||
} else {
|
||||
vs = new QueryValueSource(q, 0.0f);
|
||||
}
|
||||
|
||||
if (key==null) {
|
||||
SolrParams localParams = parser.getLocalParams();
|
||||
if (localParams != null) {
|
||||
key = localParams.get("key");
|
||||
}
|
||||
if (key == null) {
|
||||
// use the function name itself as the field name
|
||||
key = sp.val.substring(start, sp.pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (key==null) {
|
||||
key = funcStr;
|
||||
}
|
||||
okFieldNames.add( key );
|
||||
okFieldNames.add( funcStr );
|
||||
augmenters.addTransformer( new ValueSourceAugmenter( key, parser, vs ) );
|
||||
}
|
||||
catch (SyntaxError e) {
|
||||
// try again, simple rules for a field name with no whitespace
|
||||
sp.pos = start;
|
||||
field = sp.getSimpleString();
|
||||
|
||||
if (req.getSchema().getFieldOrNull(field) != null) {
|
||||
// OK, it was an oddly named field
|
||||
fields.add(field);
|
||||
if( key != null ) {
|
||||
rename.add(field, key);
|
||||
}
|
||||
} else {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// end try as function
|
||||
|
||||
} // end for(;;)
|
||||
} catch (SyntaxError e) {
|
||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error parsing fieldname", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addField(String field, String key, DocTransformers augmenters, SolrQueryRequest req)
|
||||
{
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getLuceneFieldNames()
|
||||
{
|
||||
return (_wantsAllFields || fields.isEmpty()) ? null : fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsField(String name)
|
||||
{
|
||||
if( _wantsAllFields || okFieldNames.contains( name ) ){
|
||||
return true;
|
||||
}
|
||||
for( String s : globs ) {
|
||||
// TODO something better?
|
||||
if( FilenameUtils.wildcardMatch(name, s) ) {
|
||||
okFieldNames.add(name); // Don't calculate it again
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsAllFields()
|
||||
{
|
||||
return _wantsAllFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantsScore()
|
||||
{
|
||||
return _wantsScore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocTransformer getTransformer()
|
||||
{
|
||||
return transformer;
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ import org.apache.solr.response.PythonResponseWriter;
|
|||
import org.apache.solr.response.QueryResponseWriter;
|
||||
import org.apache.solr.response.RubyResponseWriter;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -105,7 +106,7 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
|||
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||
JSONResponseWriter w = new JSONResponseWriter();
|
||||
|
||||
ReturnFields returnFields = new ReturnFields(req);
|
||||
ReturnFields returnFields = new SolrReturnFields(req);
|
||||
rsp.setReturnFields(returnFields);
|
||||
|
||||
StringWriter buf = new StringWriter();
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.solr.response.BinaryQueryResponseWriter;
|
|||
import org.apache.solr.response.BinaryResponseWriter.Resolver;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.search.ReturnFields;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
|
@ -81,7 +82,7 @@ public class TestBinaryResponseWriter extends AbstractSolrTestCase {
|
|||
in.addField("ddd_s", "ddd");
|
||||
in.addField("eee_s", "eee");
|
||||
|
||||
Resolver r = new Resolver(req, new ReturnFields(req));
|
||||
Resolver r = new Resolver(req, new SolrReturnFields(req));
|
||||
Object o = r.resolve(in, new JavaBinCodec());
|
||||
|
||||
assertNotNull("obj is null", o);
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.solr.common.SolrDocumentList;
|
|||
import org.apache.solr.common.util.DateUtil;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.search.ReturnFields;
|
||||
import org.apache.solr.search.SolrReturnFields;
|
||||
import org.junit.*;
|
||||
|
||||
import java.io.StringWriter;
|
||||
|
@ -145,19 +146,19 @@ public class TestCSVResponseWriter extends SolrTestCaseJ4 {
|
|||
rsp.add("response", sdl);
|
||||
QueryResponseWriter w = new CSVResponseWriter();
|
||||
|
||||
rsp.setReturnFields( new ReturnFields("id,foo_s", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("id,foo_s", req) );
|
||||
StringWriter buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
assertEquals("id,foo_s\n1,hi\n2,\n", buf.toString());
|
||||
|
||||
// try scores
|
||||
rsp.setReturnFields( new ReturnFields("id,score,foo_s", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("id,score,foo_s", req) );
|
||||
buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
assertEquals("id,score,foo_s\n1,2.718,hi\n2,89.83,\n", buf.toString());
|
||||
|
||||
// get field values from docs... should be ordered and not include score unless requested
|
||||
rsp.setReturnFields( new ReturnFields("*", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("*", req) );
|
||||
buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
assertEquals("id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt,v_ss,v2_ss\n" +
|
||||
|
@ -167,14 +168,14 @@ public class TestCSVResponseWriter extends SolrTestCaseJ4 {
|
|||
|
||||
|
||||
// get field values and scores - just check that the scores are there... we don't guarantee where
|
||||
rsp.setReturnFields( new ReturnFields("*,score", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("*,score", req) );
|
||||
buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
String s = buf.toString();
|
||||
assertTrue(s.indexOf("score") >=0 && s.indexOf("2.718") > 0 && s.indexOf("89.83") > 0 );
|
||||
|
||||
// Test field globs
|
||||
rsp.setReturnFields( new ReturnFields("id,foo*", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("id,foo*", req) );
|
||||
buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
assertEquals("id,foo_i,foo_s,foo_l,foo_b,foo_f,foo_d,foo_dt\n" +
|
||||
|
@ -182,7 +183,7 @@ public class TestCSVResponseWriter extends SolrTestCaseJ4 {
|
|||
"2,,,,,,,\n",
|
||||
buf.toString());
|
||||
|
||||
rsp.setReturnFields( new ReturnFields("id,*_d*", req) );
|
||||
rsp.setReturnFields( new SolrReturnFields("id,*_d*", req) );
|
||||
buf = new StringWriter();
|
||||
w.write(buf, req, rsp);
|
||||
assertEquals("id,foo_d,foo_dt\n" +
|
||||
|
|
|
@ -97,7 +97,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testSeparators() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "id name test subject score") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "id name test subject score") );
|
||||
assertTrue( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "name" ) );
|
||||
|
@ -108,7 +108,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
assertFalse( rf.wantsField( "xxx" ) );
|
||||
assertTrue( rf.getTransformer() instanceof ScoreAugmenter);
|
||||
|
||||
rf = new ReturnFields( req("fl", "id,name,test,subject,score") );
|
||||
rf = new SolrReturnFields( req("fl", "id,name,test,subject,score") );
|
||||
assertTrue( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "name" ) );
|
||||
|
@ -119,7 +119,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
assertFalse( rf.wantsField( "xxx" ) );
|
||||
assertTrue( rf.getTransformer() instanceof ScoreAugmenter);
|
||||
|
||||
rf = new ReturnFields( req("fl", "id,name test,subject score") );
|
||||
rf = new SolrReturnFields( req("fl", "id,name test,subject score") );
|
||||
assertTrue( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "name" ) );
|
||||
|
@ -130,7 +130,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
assertFalse( rf.wantsField( "xxx" ) );
|
||||
assertTrue( rf.getTransformer() instanceof ScoreAugmenter);
|
||||
|
||||
rf = new ReturnFields( req("fl", "id, name test , subject,score") );
|
||||
rf = new SolrReturnFields( req("fl", "id, name test , subject,score") );
|
||||
assertTrue( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "name" ) );
|
||||
|
@ -144,20 +144,20 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testWilcards() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "*") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "*") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "xxx" ) );
|
||||
assertTrue( rf.wantsAllFields() );
|
||||
assertNull( rf.getTransformer() );
|
||||
|
||||
rf = new ReturnFields( req("fl", " * ") );
|
||||
rf = new SolrReturnFields( req("fl", " * ") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "xxx" ) );
|
||||
assertTrue( rf.wantsAllFields() );
|
||||
assertNull( rf.getTransformer() );
|
||||
|
||||
// Check that we want wildcards
|
||||
rf = new ReturnFields( req("fl", "id,aaa*,*bbb") );
|
||||
rf = new SolrReturnFields( req("fl", "id,aaa*,*bbb") );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "aaaxxx" ) );
|
||||
assertFalse(rf.wantsField("xxxaaa"));
|
||||
|
@ -169,7 +169,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testManyParameters() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "id name", "fl", "test subject", "fl", "score") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "id name", "fl", "test subject", "fl", "score") );
|
||||
assertTrue( rf.wantsScore() );
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertTrue( rf.wantsField( "name" ) );
|
||||
|
@ -183,7 +183,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testFunctions() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "id sum(1,1)") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "id sum(1,1)") );
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue( rf.wantsField( "id" ) );
|
||||
assertFalse( rf.wantsAllFields() );
|
||||
|
@ -194,41 +194,41 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testTransformers() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "[explain]") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "[explain]") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertFalse(rf.wantsField("id"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
assertEquals( "[explain]", rf.getTransformer().getName() );
|
||||
|
||||
rf = new ReturnFields( req("fl", "[shard],id") );
|
||||
rf = new SolrReturnFields( req("fl", "[shard],id") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertTrue(rf.wantsField("id"));
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
assertEquals( "[shard]", rf.getTransformer().getName() );
|
||||
|
||||
rf = new ReturnFields( req("fl", "[docid]") );
|
||||
rf = new SolrReturnFields( req("fl", "[docid]") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertFalse( rf.wantsField( "id" ) );
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
assertEquals( "[docid]", rf.getTransformer().getName() );
|
||||
|
||||
rf = new ReturnFields( req("fl", "mydocid:[docid]") );
|
||||
rf = new SolrReturnFields( req("fl", "mydocid:[docid]") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertFalse( rf.wantsField( "id" ) );
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
assertEquals( "mydocid", rf.getTransformer().getName() );
|
||||
|
||||
rf = new ReturnFields( req("fl", "[docid][shard]") );
|
||||
rf = new SolrReturnFields( req("fl", "[docid][shard]") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
assertTrue( rf.getTransformer() instanceof DocTransformers);
|
||||
assertEquals(2, ((DocTransformers)rf.getTransformer()).size());
|
||||
|
||||
rf = new ReturnFields( req("fl", "[xxxxx]") );
|
||||
rf = new SolrReturnFields( req("fl", "[xxxxx]") );
|
||||
assertFalse( rf.wantsScore() );
|
||||
assertFalse( rf.wantsField( "id" ) );
|
||||
assertFalse(rf.wantsAllFields());
|
||||
|
@ -237,7 +237,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testAliases() {
|
||||
ReturnFields rf = new ReturnFields( req("fl", "newId:id newName:name newTest:test newSubject:subject") );
|
||||
ReturnFields rf = new SolrReturnFields( req("fl", "newId:id newName:name newTest:test newSubject:subject") );
|
||||
assertTrue(rf.wantsField("id"));
|
||||
assertTrue(rf.wantsField("name"));
|
||||
assertTrue(rf.wantsField("test"));
|
||||
|
@ -249,7 +249,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
|
||||
rf = new ReturnFields( req("fl", "newId:id newName:name newTest:test newSubject:subject score") );
|
||||
rf = new SolrReturnFields( req("fl", "newId:id newName:name newTest:test newSubject:subject score") );
|
||||
assertTrue(rf.wantsField("id"));
|
||||
assertTrue(rf.wantsField("name"));
|
||||
assertTrue(rf.wantsField("test"));
|
||||
|
@ -268,7 +268,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
// the simplest case of fl=foo-bar to work
|
||||
@Test
|
||||
public void testHyphenInFieldName() {
|
||||
ReturnFields rf = new ReturnFields(req("fl", "id-test"));
|
||||
ReturnFields rf = new SolrReturnFields(req("fl", "id-test"));
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue(rf.wantsField("id-test"));
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
|
@ -277,20 +277,20 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testTrailingDotInFieldName() {
|
||||
ReturnFields rf = new ReturnFields(req("fl", "id.test"));
|
||||
ReturnFields rf = new SolrReturnFields(req("fl", "id.test"));
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue(rf.wantsField("id.test"));
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
|
||||
rf = new ReturnFields(req("fl", "test:id.test"));
|
||||
rf = new SolrReturnFields(req("fl", "test:id.test"));
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue(rf.wantsField("id.test"));
|
||||
assertTrue(rf.wantsField("test"));
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
assertFalse(rf.wantsAllFields());
|
||||
|
||||
rf = new ReturnFields(req("fl", "test.id:id.test"));
|
||||
rf = new SolrReturnFields(req("fl", "test.id:id.test"));
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue(rf.wantsField("id.test"));
|
||||
assertTrue(rf.wantsField("test.id"));
|
||||
|
@ -300,7 +300,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
|
||||
@Test
|
||||
public void testTrailingDollarInFieldName() {
|
||||
ReturnFields rf = new ReturnFields(req("fl", "id$test"));
|
||||
ReturnFields rf = new SolrReturnFields(req("fl", "id$test"));
|
||||
assertFalse(rf.wantsScore());
|
||||
assertTrue(rf.wantsField("id$test"));
|
||||
assertFalse(rf.wantsField("xxx"));
|
||||
|
@ -325,7 +325,7 @@ public class ReturnFieldsTest extends SolrTestCaseJ4 {
|
|||
_TestUtil.randomWhitespace(r, 0, 3);
|
||||
|
||||
final String fl = id + (r.nextBoolean() ? "" : ",") + foo_i;
|
||||
ReturnFields rf = new ReturnFields(req("fl", fl));
|
||||
ReturnFields rf = new SolrReturnFields(req("fl", fl));
|
||||
|
||||
assertFalse("score ("+fl+")", rf.wantsScore());
|
||||
|
||||
|
|
Loading…
Reference in New Issue