SOLR-7957: expand ResultContext to allow for multiple DocLists per response, remove redundant TransformContext

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1698421 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2015-08-28 21:24:44 +00:00
parent 7653c36bfa
commit db78023736
33 changed files with 213 additions and 219 deletions

View File

@ -47,6 +47,12 @@ Upgrading from Solr 5.x
* The deprecated zkCredientialsProvider element in solrcloud section of solr.xml * The deprecated zkCredientialsProvider element in solrcloud section of solr.xml
is now removed. Use the correct spelling (zkCredentialsProvider) instead. is now removed. Use the correct spelling (zkCredentialsProvider) instead.
* SOLR-7957: internal/expert - ResultContext was significantly changed and expanded
to allow for multiple full query results (DocLists) per Solr request.
TransformContext was rendered redundant and was removed. (yonik)
Detailed Change List Detailed Change List
---------------------- ----------------------

View File

@ -18,7 +18,6 @@
package org.apache.solr.response; package org.apache.solr.response;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.search.DocSlice; import org.apache.solr.search.DocSlice;
import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.SolrDocumentList;
@ -50,7 +49,7 @@ public class PageTool {
results_found = doc_slice.matches(); results_found = doc_slice.matches();
start = doc_slice.offset(); start = doc_slice.offset();
} else if(docs instanceof ResultContext) { } else if(docs instanceof ResultContext) {
DocList dl = ((ResultContext) docs).docs; DocList dl = ((ResultContext) docs).getDocList();
results_found = dl.matches(); results_found = dl.matches();
start = dl.offset(); start = dl.offset();
} else if(docs instanceof SolrDocumentList) { } else if(docs instanceof SolrDocumentList) {

View File

@ -189,9 +189,9 @@ public class EmbeddedSolrServer extends SolrClient {
public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException { public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException {
// write an empty list... // write an empty list...
SolrDocumentList docs = new SolrDocumentList(); SolrDocumentList docs = new SolrDocumentList();
docs.setNumFound(ctx.docs.matches()); docs.setNumFound(ctx.getDocList().matches());
docs.setStart(ctx.docs.offset()); docs.setStart(ctx.getDocList().offset());
docs.setMaxScore(ctx.docs.maxScore()); docs.setMaxScore(ctx.getDocList().maxScore());
codec.writeSolrDocumentList(docs); codec.writeSolrDocumentList(docs);
// This will transform // This will transform

View File

@ -70,7 +70,7 @@ public class QuerySenderListener extends AbstractSolrEventListener {
for (int i=0; i<values.size(); i++) { for (int i=0; i<values.size(); i++) {
Object o = values.getVal(i); Object o = values.getVal(i);
if (o instanceof ResultContext) { if (o instanceof ResultContext) {
o = ((ResultContext)o).docs; o = ((ResultContext)o).getDocList();
} }
if (o instanceof DocList) { if (o instanceof DocList) {
DocList docs = (DocList)o; DocList docs = (DocList)o;

View File

@ -36,7 +36,6 @@ import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil; import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.LeafFieldComparator; import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.MatchNoDocsQuery;
@ -66,6 +65,7 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap; import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.StrUtils;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.BasicResultContext;
import org.apache.solr.response.ResultContext; import org.apache.solr.response.ResultContext;
import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
@ -348,9 +348,7 @@ public class QueryComponent extends SearchComponent
} }
rb.setResults(res); rb.setResults(res);
ResultContext ctx = new ResultContext(); ResultContext ctx = new BasicResultContext(rb);
ctx.docs = rb.getResults().docList;
ctx.query = null; // anything?
rsp.add("response", ctx); rsp.add("response", ctx);
return; return;
} }
@ -503,9 +501,7 @@ public class QueryComponent extends SearchComponent
rb.setResult(result); rb.setResult(result);
if (grouping.mainResult != null) { if (grouping.mainResult != null) {
ResultContext ctx = new ResultContext(); ResultContext ctx = new BasicResultContext(rb, grouping.mainResult);
ctx.docs = grouping.mainResult;
ctx.query = null; // TODO? add the query?
rsp.add("response", ctx); rsp.add("response", ctx);
rsp.getToLog().add("hits", grouping.mainResult.matches()); rsp.getToLog().add("hits", grouping.mainResult.matches());
} else if (!grouping.getCommands().isEmpty()) { // Can never be empty since grouping.execute() checks for this. } else if (!grouping.getCommands().isEmpty()) { // Can never be empty since grouping.execute() checks for this.
@ -522,9 +518,7 @@ public class QueryComponent extends SearchComponent
searcher.search(result, cmd); searcher.search(result, cmd);
rb.setResult(result); rb.setResult(result);
ResultContext ctx = new ResultContext(); ResultContext ctx = new BasicResultContext(rb);
ctx.docs = rb.getResults().docList;
ctx.query = rb.getQuery();
rsp.add("response", ctx); rsp.add("response", ctx);
rsp.getToLog().add("hits", rb.getResults().docList.matches()); rsp.getToLog().add("hits", rb.getResults().docList.matches());

View File

@ -50,9 +50,10 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.StrUtils; import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.BasicResultContext;
import org.apache.solr.response.ResultContext;
import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.response.transform.DocTransformer; import org.apache.solr.response.transform.DocTransformer;
import org.apache.solr.response.transform.TransformContext;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.SchemaField;
@ -153,8 +154,7 @@ public class RealTimeGetComponent extends SearchComponent
DocTransformer transformer = rsp.getReturnFields().getTransformer(); DocTransformer transformer = rsp.getReturnFields().getTransformer();
if (transformer != null) { if (transformer != null) {
TransformContext context = new TransformContext(); ResultContext context = new BasicResultContext(null, rsp.getReturnFields(), null, null, req);
context.req = req;
transformer.setContext(context); transformer.setContext(context);
} }
try { try {
@ -174,7 +174,7 @@ public class RealTimeGetComponent extends SearchComponent
case UpdateLog.ADD: case UpdateLog.ADD:
SolrDocument doc = toSolrDoc((SolrInputDocument)entry.get(entry.size()-1), core.getLatestSchema()); SolrDocument doc = toSolrDoc((SolrInputDocument)entry.get(entry.size()-1), core.getLatestSchema());
if(transformer!=null) { if(transformer!=null) {
transformer.transform(doc, -1); // unknown docID transformer.transform(doc, -1, 0); // unknown docID
} }
docList.add(doc); docList.add(doc);
break; break;
@ -200,7 +200,7 @@ public class RealTimeGetComponent extends SearchComponent
StoredDocument luceneDocument = searcher.doc(docid, rsp.getReturnFields().getLuceneFieldNames()); StoredDocument luceneDocument = searcher.doc(docid, rsp.getReturnFields().getLuceneFieldNames());
SolrDocument doc = toSolrDoc(luceneDocument, core.getLatestSchema()); SolrDocument doc = toSolrDoc(luceneDocument, core.getLatestSchema());
if( transformer != null ) { if( transformer != null ) {
transformer.transform(doc, docid); transformer.transform(doc, docid, 0);
} }
docList.add(doc); docList.add(doc);
} }

View File

@ -72,10 +72,11 @@ public class ResponseLogComponent extends SearchComponent {
ResultContext rc = (ResultContext) rb.rsp.getValues().get("response"); ResultContext rc = (ResultContext) rb.rsp.getValues().get("response");
if (rc.docs.hasScores()) { DocList docs = rc.getDocList();
processScores(rb, rc.docs, schema, searcher); if (docs.hasScores()) {
processScores(rb, docs, schema, searcher);
} else { } else {
processIds(rb, rc.docs, schema, searcher); processIds(rb, docs, schema, searcher);
} }
} }

View File

@ -0,0 +1,76 @@
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 org.apache.lucene.search.Query;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DocList;
import org.apache.solr.search.ReturnFields;
import org.apache.solr.search.SolrIndexSearcher;
public class BasicResultContext extends ResultContext {
private DocList docList;
private ReturnFields returnFields;
private SolrIndexSearcher searcher;
private Query query;
private SolrQueryRequest req;
public BasicResultContext(DocList docList, ReturnFields returnFields, SolrIndexSearcher searcher, Query query, SolrQueryRequest req) {
this.docList = docList;
this.returnFields = returnFields;
this.searcher = searcher;
this.query = query;
this.req = req;
}
public BasicResultContext(ResponseBuilder rb) {
this(rb.getResults().docList, rb.rsp.getReturnFields(), null, rb.getQuery(), rb.req);
}
public BasicResultContext(ResponseBuilder rb, DocList docList) {
this(docList, rb.rsp.getReturnFields(), null, rb.getQuery(), rb.req);
}
@Override
public DocList getDocList() {
return docList;
}
@Override
public ReturnFields getReturnFields() {
return returnFields;
}
@Override
public SolrIndexSearcher getSearcher() {
if (searcher != null) return searcher;
if (req != null) return req.getSearcher();
return null;
}
@Override
public Query getQuery() {
return query;
}
@Override
public SolrQueryRequest getRequest() {
return req;
}
}

View File

@ -23,11 +23,10 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.lucene.index.StorableField; import org.apache.lucene.index.StorableField;
import org.apache.lucene.index.StoredDocument;
import org.apache.lucene.index.IndexableField;
import org.apache.solr.client.solrj.impl.BinaryResponseParser; import org.apache.solr.client.solrj.impl.BinaryResponseParser;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.CommonParams;
@ -39,7 +38,6 @@ import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.search.ReturnFields; import org.apache.solr.search.ReturnFields;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.search.SolrReturnFields;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -73,7 +71,7 @@ public class BinaryResponseWriter implements BinaryQueryResponseWriter {
public static class Resolver implements JavaBinCodec.ObjectResolver , JavaBinCodec.WritableDocFields { public static class Resolver implements JavaBinCodec.ObjectResolver , JavaBinCodec.WritableDocFields {
protected final SolrQueryRequest solrQueryRequest; protected final SolrQueryRequest solrQueryRequest;
protected IndexSchema schema; protected IndexSchema schema;
protected SolrIndexSearcher searcher; protected SolrIndexSearcher searcher; // TODO - this is never set? always null?
protected final ReturnFields returnFields; protected final ReturnFields returnFields;
public Resolver(SolrQueryRequest req, ReturnFields returnFields) { public Resolver(SolrQueryRequest req, ReturnFields returnFields) {
@ -88,8 +86,7 @@ public class BinaryResponseWriter implements BinaryQueryResponseWriter {
return null; // null means we completely handled it return null; // null means we completely handled it
} }
if (o instanceof DocList) { if (o instanceof DocList) {
ResultContext ctx = new ResultContext(); ResultContext ctx = new BasicResultContext((DocList)o, returnFields, null, null, solrQueryRequest);
ctx.docs = (DocList) o;
writeResults(ctx, codec); writeResults(ctx, codec);
return null; // null means we completely handled it return null; // null means we completely handled it
} }
@ -118,8 +115,8 @@ public class BinaryResponseWriter implements BinaryQueryResponseWriter {
} }
protected void writeResultsBody( ResultContext res, JavaBinCodec codec ) throws IOException { protected void writeResultsBody( ResultContext res, JavaBinCodec codec ) throws IOException {
codec.writeTag(JavaBinCodec.ARR, res.docs.size()); codec.writeTag(JavaBinCodec.ARR, res.getDocList().size());
DocsStreamer docStreamer = new DocsStreamer(res.docs,res.query, solrQueryRequest, returnFields); Iterator<SolrDocument> docStreamer = res.getProcessedDocuments();
while (docStreamer.hasNext()) { while (docStreamer.hasNext()) {
SolrDocument doc = docStreamer.next(); SolrDocument doc = docStreamer.next();
codec.writeSolrDocument(doc); codec.writeSolrDocument(doc);
@ -128,14 +125,13 @@ public class BinaryResponseWriter implements BinaryQueryResponseWriter {
public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException { public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException {
codec.writeTag(JavaBinCodec.SOLRDOCLST); codec.writeTag(JavaBinCodec.SOLRDOCLST);
boolean wantsScores = returnFields.wantsScore() && ctx.docs.hasScores();
List l = new ArrayList(3); List l = new ArrayList(3);
l.add((long) ctx.docs.matches()); l.add((long) ctx.getDocList().matches());
l.add((long) ctx.docs.offset()); l.add((long) ctx.getDocList().offset());
Float maxScore = null; Float maxScore = null;
if (wantsScores) { if (ctx.wantsScores()) {
maxScore = ctx.docs.maxScore(); maxScore = ctx.getDocList().maxScore();
} }
l.add(maxScore); l.add(maxScore);
codec.writeArray(l); codec.writeArray(l);

View File

@ -340,13 +340,13 @@ class CSVWriter extends TextResponseWriter {
printer.println(); printer.println();
} }
if (responseObj instanceof ResultContext ) { if (responseObj instanceof ResultContext) {
writeDocuments(null, (ResultContext)responseObj, returnFields ); writeDocuments(null, (ResultContext)responseObj );
} }
else if (responseObj instanceof DocList) { else if (responseObj instanceof DocList) {
ResultContext ctx = new ResultContext();
ctx.docs = (DocList)responseObj; ResultContext ctx = new BasicResultContext((DocList)responseObj, returnFields, null, null, req);
writeDocuments(null, ctx, returnFields ); writeDocuments(null, ctx );
} else if (responseObj instanceof SolrDocumentList) { } else if (responseObj instanceof SolrDocumentList) {
writeSolrDocumentList(null, (SolrDocumentList)responseObj, returnFields ); writeSolrDocumentList(null, (SolrDocumentList)responseObj, returnFields );
} }

View File

@ -24,17 +24,12 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexableField;
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.lucene.search.Query;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.transform.DocTransformer; import org.apache.solr.response.transform.DocTransformer;
import org.apache.solr.response.transform.TransformContext;
import org.apache.solr.schema.BinaryField; import org.apache.solr.schema.BinaryField;
import org.apache.solr.schema.BoolField; import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
@ -50,8 +45,6 @@ import org.apache.solr.schema.TrieIntField;
import org.apache.solr.schema.TrieLongField; import org.apache.solr.schema.TrieLongField;
import org.apache.solr.search.DocIterator; import org.apache.solr.search.DocIterator;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.search.ReturnFields;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.search.SolrReturnFields; import org.apache.solr.search.SolrReturnFields;
/** /**
@ -59,38 +52,28 @@ import org.apache.solr.search.SolrReturnFields;
*/ */
public class DocsStreamer implements Iterator<SolrDocument> { public class DocsStreamer implements Iterator<SolrDocument> {
public static final Set<Class> KNOWN_TYPES = new HashSet<>(); public static final Set<Class> KNOWN_TYPES = new HashSet<>();
private org.apache.solr.response.ResultContext rctx;
private final DocList docs; private final DocList docs;
private SolrIndexSearcher searcher;
private final IndexSchema schema;
private DocTransformer transformer; private DocTransformer transformer;
private DocIterator docIterator; private DocIterator docIterator;
private boolean onlyPseudoFields; private boolean onlyPseudoFields;
private Set<String> fnames; private Set<String> fnames;
private TransformContext context;
private int idx = -1; private int idx = -1;
public DocsStreamer(DocList docList, Query query, SolrQueryRequest req, ReturnFields returnFields) { public DocsStreamer(ResultContext rctx) {
this.docs = docList; this.rctx = rctx;
this.schema = req.getSchema(); this.docs = rctx.getDocList();
searcher = req.getSearcher(); transformer = rctx.getReturnFields().getTransformer();
transformer = returnFields.getTransformer(); docIterator = this.docs.iterator();
docIterator = docList.iterator(); fnames = rctx.getReturnFields().getLuceneFieldNames();
context = new TransformContext(); onlyPseudoFields = (fnames == null && !rctx.getReturnFields().wantsAllFields() && !rctx.getReturnFields().hasPatternMatching())
context.query = query;
context.wantsScores = returnFields.wantsScore() && docList.hasScores();
context.req = req;
context.searcher = searcher;
context.iterator = docIterator;
fnames = returnFields.getLuceneFieldNames();
onlyPseudoFields = (fnames == null && !returnFields.wantsAllFields() && !returnFields.hasPatternMatching())
|| (fnames != null && fnames.size() == 1 && SolrReturnFields.SCORE.equals(fnames.iterator().next())); || (fnames != null && fnames.size() == 1 && SolrReturnFields.SCORE.equals(fnames.iterator().next()));
if (transformer != null) transformer.setContext(context); if (transformer != null) transformer.setContext(rctx);
} }
public boolean hasScores() {
return context.wantsScores;
}
public int currentIndex() { public int currentIndex() {
return idx; return idx;
@ -110,16 +93,17 @@ public class DocsStreamer implements Iterator<SolrDocument> {
sdoc = new SolrDocument(); sdoc = new SolrDocument();
} else { } else {
try { try {
StoredDocument doc = searcher.doc(id, fnames); StoredDocument doc = rctx.getSearcher().doc(id, fnames);
sdoc = getDoc(doc, schema); sdoc = getDoc(doc, rctx.getSearcher().getSchema()); // make sure to use the schema from the searcher and not the request (cross-core)
} catch (IOException e) { } catch (IOException e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error reading document with docId " + id, e); throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error reading document with docId " + id, e);
} }
} }
if (transformer != null) { if (transformer != null) {
boolean doScore = rctx.wantsScores();
try { try {
transformer.transform(sdoc, id); transformer.transform(sdoc, id, doScore ? docIterator.score() : 0);
} catch (IOException e) { } catch (IOException e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error applying transformer", e); throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error applying transformer", e);
} }

View File

@ -17,15 +17,45 @@
package org.apache.solr.response; package org.apache.solr.response;
import java.util.Iterator;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.search.ReturnFields;
import org.apache.solr.search.SolrIndexSearcher;
/** /**
* A class to hold the QueryResult and the Query * A class to hold the QueryResult and the Query
* *
* *
*/ */
public class ResultContext { public abstract class ResultContext {
public Query query;
public DocList docs; public abstract DocList getDocList();
public abstract ReturnFields getReturnFields();
public abstract SolrIndexSearcher getSearcher();
public abstract Query getQuery();
// TODO: any reason to allow for retrievial of any filters as well?
/** Note: do not use the request to get the searcher! A cross-core request may have a different
* searcher (for the other core) than the original request.
*/
public abstract SolrQueryRequest getRequest();
public boolean wantsScores() {
return getReturnFields().wantsScore() && getDocList().hasScores();
}
public Iterator<SolrDocument> getProcessedDocuments() {
return new DocsStreamer(this);
}
} }

View File

@ -144,12 +144,11 @@ public abstract class TextResponseWriter {
writeSolrDocument(name, (SolrDocument)val,returnFields, 0); writeSolrDocument(name, (SolrDocument)val,returnFields, 0);
} else if (val instanceof ResultContext) { } else if (val instanceof ResultContext) {
// requires access to IndexReader // requires access to IndexReader
writeDocuments(name, (ResultContext)val, returnFields); writeDocuments(name, (ResultContext)val);
} else if (val instanceof DocList) { } else if (val instanceof DocList) {
// Should not happen normally // Should not happen normally
ResultContext ctx = new ResultContext(); ResultContext ctx = new BasicResultContext((DocList)val, returnFields, null, null, req);
ctx.docs = (DocList)val; writeDocuments(name, ctx);
writeDocuments(name, ctx, returnFields);
// } // }
// else if (val instanceof DocSet) { // else if (val instanceof DocSet) {
// how do we know what fields to read? // how do we know what fields to read?
@ -216,29 +215,31 @@ public abstract class TextResponseWriter {
public abstract void writeStartDocumentList(String name, long start, int size, long numFound, Float maxScore) throws IOException; public abstract void writeStartDocumentList(String name, long start, int size, long numFound, Float maxScore) throws IOException;
public abstract void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException; public abstract void writeSolrDocument(String name, SolrDocument doc, ReturnFields fields, int idx) throws IOException;
public abstract void writeEndDocumentList() throws IOException; public abstract void writeEndDocumentList() throws IOException;
// Assume each SolrDocument is already transformed // Assume each SolrDocument is already transformed
public final void writeSolrDocumentList(String name, SolrDocumentList docs, ReturnFields returnFields) throws IOException public final void writeSolrDocumentList(String name, SolrDocumentList docs, ReturnFields fields) throws IOException
{ {
writeStartDocumentList(name, docs.getStart(), docs.size(), docs.getNumFound(), docs.getMaxScore() ); writeStartDocumentList(name, docs.getStart(), docs.size(), docs.getNumFound(), docs.getMaxScore() );
for( int i=0; i<docs.size(); i++ ) { for( int i=0; i<docs.size(); i++ ) {
writeSolrDocument( null, docs.get(i), returnFields, i ); writeSolrDocument( null, docs.get(i), fields, i );
} }
writeEndDocumentList(); writeEndDocumentList();
} }
public final void writeDocuments(String name, ResultContext res, ReturnFields fields ) throws IOException { public final void writeDocuments(String name, ResultContext res) throws IOException {
DocList ids = res.docs; DocList ids = res.getDocList();
DocsStreamer docsStreamer = new DocsStreamer(res.docs,res.query, req, fields); Iterator<SolrDocument> docsStreamer = res.getProcessedDocuments();
writeStartDocumentList(name, ids.offset(), ids.size(), ids.matches(), writeStartDocumentList(name, ids.offset(), ids.size(), ids.matches(),
docsStreamer.hasScores() ? new Float(ids.maxScore()) : null); res.wantsScores() ? new Float(ids.maxScore()) : null);
int idx = 0;
while (docsStreamer.hasNext()) { while (docsStreamer.hasNext()) {
writeSolrDocument(null, docsStreamer.next(), returnFields, docsStreamer.currentIndex()); writeSolrDocument(null, docsStreamer.next(), res.getReturnFields(), idx);
idx++;
} }
writeEndDocumentList(); writeEndDocumentList();
} }

View File

@ -47,7 +47,7 @@ public abstract class BaseEditorialTransformer extends DocTransformer {
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
//this only gets added if QueryElevationParams.MARK_EXCLUDED is true //this only gets added if QueryElevationParams.MARK_EXCLUDED is true
Set<String> ids = getIdSet(); Set<String> ids = getIdSet();
if (ids != null && ids.isEmpty() == false) { if (ids != null && ids.isEmpty() == false) {

View File

@ -96,7 +96,7 @@ public class ChildDocTransformerFactory extends TransformerFactory {
} }
} }
class ChildDocTransformer extends TransformerWithContext { class ChildDocTransformer extends DocTransformer {
private final String name; private final String name;
private final SchemaField idField; private final SchemaField idField;
private final IndexSchema schema; private final IndexSchema schema;
@ -121,7 +121,7 @@ class ChildDocTransformer extends TransformerWithContext {
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
FieldType idFt = idField.getType(); FieldType idFt = idField.getType();
Object parentIdField = doc.getFirstValue(idField.getName()); Object parentIdField = doc.getFirstValue(idField.getName());
@ -133,12 +133,12 @@ class ChildDocTransformer extends TransformerWithContext {
try { try {
Query parentQuery = idFt.getFieldQuery(null, idField, parentIdExt); Query parentQuery = idFt.getFieldQuery(null, idField, parentIdExt);
Query query = new ToChildBlockJoinQuery(parentQuery, parentsFilter); Query query = new ToChildBlockJoinQuery(parentQuery, parentsFilter);
DocList children = context.searcher.getDocList(query, childFilterQuery, new Sort(), 0, limit); DocList children = context.getSearcher().getDocList(query, childFilterQuery, new Sort(), 0, limit);
if(children.matches() > 0) { if(children.matches() > 0) {
DocIterator i = children.iterator(); DocIterator i = children.iterator();
while(i.hasNext()) { while(i.hasNext()) {
Integer childDocNum = i.next(); Integer childDocNum = i.next();
StoredDocument childDoc = context.searcher.doc(childDocNum); StoredDocument childDoc = context.getSearcher().doc(childDocNum);
SolrDocument solrChildDoc = DocsStreamer.getDoc(childDoc, schema); SolrDocument solrChildDoc = DocsStreamer.getDoc(childDoc, schema);
// TODO: future enhancement... // TODO: future enhancement...

View File

@ -48,7 +48,7 @@ class DocIdAugmenter extends DocTransformer
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
if( docid >= 0 ) { if( docid >= 0 ) {
doc.setField( name, docid ); doc.setField( name, docid );
} }

View File

@ -18,10 +18,10 @@
package org.apache.solr.response.transform; package org.apache.solr.response.transform;
import java.io.IOException; import java.io.IOException;
import java.util.Set;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.response.QueryResponseWriter; import org.apache.solr.response.QueryResponseWriter;
import org.apache.solr.response.ResultContext;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
/** /**
@ -35,7 +35,7 @@ import org.apache.solr.search.SolrIndexSearcher;
* *
*/ */
public abstract class DocTransformer { public abstract class DocTransformer {
protected TransformContext context; protected ResultContext context;
/** /**
* *
* @return The name of the transformer * @return The name of the transformer
@ -44,10 +44,9 @@ public abstract class DocTransformer {
/** /**
* This is called before transform and sets * This is called before transform and sets
* @param context The {@link org.apache.solr.response.transform.TransformContext} stores information about the current state of things in Solr that may be * @param context The {@link ResultContext} stores information about how the documents were produced.
* useful for doing transformations.
*/ */
public void setContext( TransformContext context ) { public void setContext( ResultContext context ) {
this.context = context; this.context = context;
} }
@ -58,9 +57,10 @@ public abstract class DocTransformer {
* *
* @param doc The document to alter * @param doc The document to alter
* @param docid The Lucene internal doc id * @param docid The Lucene internal doc id
* @param score
* @throws IOException If there is a low-level I/O error. * @throws IOException If there is a low-level I/O error.
*/ */
public abstract void transform(SolrDocument doc, int docid) throws IOException; public abstract void transform(SolrDocument doc, int docid, float score) throws IOException;
/** /**
* When a transformer needs access to fields that are not automaticaly derived from the * When a transformer needs access to fields that are not automaticaly derived from the

View File

@ -23,7 +23,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.response.ResultContext;
/** /**
* Transform a document before it gets sent out * Transform a document before it gets sent out
@ -65,16 +65,16 @@ public class DocTransformers extends DocTransformer
} }
@Override @Override
public void setContext( TransformContext context ) { public void setContext( ResultContext context ) {
for( DocTransformer a : children ) { for( DocTransformer a : children ) {
a.setContext( context ); a.setContext( context );
} }
} }
@Override @Override
public void transform(SolrDocument doc, int docid) throws IOException { public void transform(SolrDocument doc, int docid, float score) throws IOException {
for( DocTransformer a : children ) { for( DocTransformer a : children ) {
a.transform( doc, docid); a.transform( doc, docid, score);
} }
} }
} }

View File

@ -48,7 +48,7 @@ class MarkTransformer extends BaseEditorialTransformer {
@Override @Override
protected Set<String> getIdSet() { protected Set<String> getIdSet() {
return (Set<String>) context.req.getContext().get("BOOSTED"); return (Set<String>) context.getRequest().getContext().get("BOOSTED");
} }
} }

View File

@ -51,7 +51,7 @@ class ExcludedTransformer extends BaseEditorialTransformer {
@Override @Override
protected Set<String> getIdSet() { protected Set<String> getIdSet() {
return (Set<String>)context.req.getContext().get(QueryElevationComponent.EXCLUDED); return (Set<String>)context.getRequest().getContext().get(QueryElevationComponent.EXCLUDED);
} }
} }

View File

@ -87,7 +87,7 @@ public class ExplainAugmenterFactory extends TransformerFactory
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
if( context != null && context.getQuery() != null ) { if( context != null && context.getQuery() != null ) {
try { try {
Explanation exp = context.getSearcher().explain(context.getQuery(), docid); Explanation exp = context.getSearcher().explain(context.getQuery(), docid);

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.StorableField; import org.apache.lucene.index.StorableField;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.CommonParams;
@ -108,7 +107,7 @@ public class RawValueTransformerFactory extends TransformerFactory
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
Object val = doc.remove(field); Object val = doc.remove(field);
if(val==null) { if(val==null) {
return; return;

View File

@ -17,8 +17,6 @@
package org.apache.solr.response.transform; package org.apache.solr.response.transform;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrQueryRequest;
/** /**
* Return a field with a name that is different that what is indexed * Return a field with a name that is different that what is indexed
@ -46,7 +44,7 @@ public class RenameFieldTransformer extends DocTransformer
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
Object v = (copy)?doc.get(from) : doc.remove( from ); Object v = (copy)?doc.get(from) : doc.remove( from );
if( v != null ) { if( v != null ) {
doc.setField(to, v); doc.setField(to, v);

View File

@ -17,7 +17,6 @@
package org.apache.solr.response.transform; package org.apache.solr.response.transform;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.request.SolrQueryRequest;
/** /**
* Simple Augmenter that adds the score * Simple Augmenter that adds the score
@ -40,11 +39,9 @@ public class ScoreAugmenter extends DocTransformer {
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
if( context != null && context.wantsScores() ) { if( context != null && context.wantsScores() ) {
if( context.getDocIterator() != null ) { doc.setField( name, score );
doc.setField( name, context.getDocIterator().score() );
}
} }
} }
} }

View File

@ -1,56 +0,0 @@
/*
* 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.response.transform;
import org.apache.lucene.search.Query;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.search.DocIterator;
import org.apache.solr.search.SolrIndexSearcher;
/**
* Environment variables for the transformed documents
*
*
* @since solr 4.0
*/
public class TransformContext {
public Query query;
public boolean wantsScores = false;
public DocIterator iterator;
public SolrIndexSearcher searcher;
public SolrQueryRequest req;
public Query getQuery() {
return query;
}
public boolean wantsScores() {
return wantsScores;
}
public DocIterator getDocIterator() {
return iterator;
}
public SolrIndexSearcher getSearcher() {
return searcher;
}
public SolrQueryRequest getRequest() {
return req;
}
}

View File

@ -1,31 +0,0 @@
/*
* 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.response.transform;
/**
*
* @since solr 4.0
*/
@Deprecated
public abstract class TransformerWithContext extends DocTransformer
{
@Override
public void setContext( TransformContext context ) {
this.context = context;
}
}

View File

@ -96,7 +96,7 @@ class ValueAugmenter extends DocTransformer
} }
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
doc.setField( name, value ); doc.setField( name, value );
} }
} }

View File

@ -27,6 +27,7 @@ import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.queries.function.ValueSource;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.response.ResultContext;
import org.apache.solr.search.QParser; import org.apache.solr.search.QParser;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
@ -60,7 +61,8 @@ public class ValueSourceAugmenter extends DocTransformer
} }
@Override @Override
public void setContext( TransformContext context ) { public void setContext( ResultContext context ) {
super.setContext(context);
try { try {
IndexReader reader = qparser.getReq().getSearcher().getIndexReader(); IndexReader reader = qparser.getReq().getSearcher().getIndexReader();
readerContexts = reader.leaves(); readerContexts = reader.leaves();
@ -82,7 +84,7 @@ public class ValueSourceAugmenter extends DocTransformer
@Override @Override
public void transform(SolrDocument doc, int docid) { public void transform(SolrDocument doc, int docid, float score) {
// This is only good for random-access functions // This is only good for random-access functions
try { try {

View File

@ -710,7 +710,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
SolrQueryResponse rsp = new SolrQueryResponse(); SolrQueryResponse rsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp); core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp);
DocList dl = ((ResultContext) rsp.getValues().get("response")).docs; DocList dl = ((ResultContext) rsp.getValues().get("response")).getDocList();
StoredDocument d = req.getSearcher().doc(dl.iterator().nextDoc()); StoredDocument d = req.getSearcher().doc(dl.iterator().nextDoc());
// ensure field in fl is not lazy // ensure field in fl is not lazy
assertFalse( ((Field) d.getField("test_hlt")).getClass().getSimpleName().equals("LazyField")); assertFalse( ((Field) d.getField("test_hlt")).getClass().getSimpleName().equals("LazyField"));
@ -735,7 +735,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
SolrQueryResponse rsp = new SolrQueryResponse(); SolrQueryResponse rsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp); core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp);
DocList dl = ((ResultContext) rsp.getValues().get("response")).docs; DocList dl = ((ResultContext) rsp.getValues().get("response")).getDocList();
DocIterator di = dl.iterator(); DocIterator di = dl.iterator();
StoredDocument d1 = req.getSearcher().doc(di.nextDoc()); StoredDocument d1 = req.getSearcher().doc(di.nextDoc());
StorableField[] values1 = null; StorableField[] values1 = null;
@ -757,7 +757,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
rsp = new SolrQueryResponse(); rsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp); core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp);
dl = ((ResultContext) rsp.getValues().get("response")).docs; dl = ((ResultContext) rsp.getValues().get("response")).getDocList();
di = dl.iterator(); di = dl.iterator();
StoredDocument d2 = req.getSearcher().doc(di.nextDoc()); StoredDocument d2 = req.getSearcher().doc(di.nextDoc());
// ensure same doc, same lazy field now // ensure same doc, same lazy field now

View File

@ -264,7 +264,7 @@ public class TestGroupingSearch extends SolrTestCaseJ4 {
SolrRequestInfo.clearRequestInfo(); SolrRequestInfo.clearRequestInfo();
} }
assertEquals(6, ((ResultContext) response.getValues().get("response")).docs.matches()); assertEquals(6, ((ResultContext) response.getValues().get("response")).getDocList().matches());
new BinaryResponseParser().processResponse(new ByteArrayInputStream(out.toByteArray()), ""); new BinaryResponseParser().processResponse(new ByteArrayInputStream(out.toByteArray()), "");
out.close(); out.close();
} }

View File

@ -19,8 +19,6 @@ package org.apache.solr.response;
import java.io.IOException; import java.io.IOException;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.StorableField; import org.apache.lucene.index.StorableField;
import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocument;
@ -108,7 +106,7 @@ public class TestCustomDocTransformer extends SolrTestCaseJ4 {
* This transformer simply concatinates the values of multipe fields * This transformer simply concatinates the values of multipe fields
*/ */
@Override @Override
public void transform(SolrDocument doc, int docid) throws IOException { public void transform(SolrDocument doc, int docid, float score) throws IOException {
str.setLength(0); str.setLength(0);
for(String s : extra) { for(String s : extra) {
String v = getAsString(s, doc); String v = getAsString(s, doc);

View File

@ -259,8 +259,8 @@ public class TestRangeQuery extends SolrTestCaseJ4 {
SolrQueryResponse qr = h.queryAndResponse(handler, req); SolrQueryResponse qr = h.queryAndResponse(handler, req);
if (last != null) { if (last != null) {
// we only test if the same docs matched since some queries will include factors like idf, etc. // we only test if the same docs matched since some queries will include factors like idf, etc.
DocList rA = ((ResultContext)qr.getValues().get("response")).docs; DocList rA = ((ResultContext)qr.getValues().get("response")).getDocList();
DocList rB = ((ResultContext)last.getValues().get("response")).docs; DocList rB = ((ResultContext)last.getValues().get("response")).getDocList();
sameDocs( rA, rB ); sameDocs( rA, rB );
} }
req.close(); req.close();

View File

@ -33,6 +33,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField; import org.apache.solr.common.SolrInputField;
import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrCore;
import org.apache.solr.response.ResultContext;
import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.search.DocList; import org.apache.solr.search.DocList;
import org.apache.solr.schema.CopyField; import org.apache.solr.schema.CopyField;
@ -40,7 +41,6 @@ import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.IndexSchema; import org.apache.solr.schema.IndexSchema;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse; import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.response.ResultContext;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -345,7 +345,7 @@ public class DocumentBuilderTest extends SolrTestCaseJ4 {
SolrQueryResponse rsp = new SolrQueryResponse(); SolrQueryResponse rsp = new SolrQueryResponse();
core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp); core.execute(core.getRequestHandler(req.getParams().get(CommonParams.QT)), req, rsp);
DocList dl = ((ResultContext) rsp.getValues().get("response")).docs; DocList dl = ((ResultContext) rsp.getValues().get("response")).getDocList();
assertTrue("can't find the doc we just added", 1 == dl.size()); assertTrue("can't find the doc we just added", 1 == dl.size());
int docid = dl.iterator().nextDoc(); int docid = dl.iterator().nextDoc();