mirror of https://github.com/apache/lucene.git
SOLR-446: TextResponseWriter can write SolrDocuments and SolrDocumentLists the same way it writes Document and DocList.
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@610156 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7c660c8526
commit
a405feac80
|
@ -181,6 +181,10 @@ New Features
|
|||
The jsp files /admin/get-file.jsp and /admin/raw-schema.jsp have been deprecated.
|
||||
(ryan)
|
||||
|
||||
36. SOLR-446: TextResponseWriter can write SolrDocuments and SolrDocumentLists the
|
||||
same way it writes Document and DocList. (yonik, ryan)
|
||||
|
||||
|
||||
Changes in runtime behavior
|
||||
|
||||
Optimizations
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.apache.solr.request;
|
|||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
|
@ -386,6 +388,47 @@ class JSONWriter extends TextResponseWriter {
|
|||
writeMapCloser();
|
||||
}
|
||||
|
||||
public void writeSolrDocument(String name, SolrDocument doc, Set<String> returnFields, Map pseudoFields) throws IOException {
|
||||
writeMapOpener(-1); // no trivial way to determine map size
|
||||
// TODO: could easily figure out size for SolrDocument if needed...
|
||||
incLevel();
|
||||
|
||||
boolean first=true;
|
||||
for (String fname : doc.getFieldNames()) {
|
||||
if (first) {
|
||||
first=false;
|
||||
}
|
||||
else {
|
||||
writeMapSeparator();
|
||||
}
|
||||
|
||||
indent();
|
||||
writeKey(fname, true);
|
||||
Object val = doc.getFieldValue(fname);
|
||||
|
||||
if (val instanceof Collection) {
|
||||
writeVal(fname, val);
|
||||
} else {
|
||||
// if multivalued field, write single value as an array
|
||||
SchemaField sf = schema.getFieldOrNull(fname);
|
||||
if (sf != null && sf.multiValued()) {
|
||||
writeArrayOpener(-1); // no trivial way to determine array size
|
||||
writeVal(fname, val);
|
||||
writeArrayCloser();
|
||||
}
|
||||
writeVal(fname, val);
|
||||
}
|
||||
|
||||
if (pseudoFields !=null && pseudoFields.size()>0) {
|
||||
writeMap(null,pseudoFields,true,first);
|
||||
}
|
||||
}
|
||||
|
||||
decLevel();
|
||||
writeMapCloser();
|
||||
}
|
||||
|
||||
|
||||
// reusable map to store the "score" pseudo-field.
|
||||
// if a Doc can ever contain another doc, this optimization would have to go.
|
||||
private final HashMap scoreMap = new HashMap(1);
|
||||
|
@ -457,6 +500,64 @@ class JSONWriter extends TextResponseWriter {
|
|||
writeMapCloser();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeSolrDocumentList(String name, SolrDocumentList docs, Set<String> fields, Map otherFields) throws IOException {
|
||||
boolean includeScore=false;
|
||||
if (fields!=null) {
|
||||
includeScore = fields.contains("score");
|
||||
if (fields.size()==0 || (fields.size()==1 && includeScore) || fields.contains("*")) {
|
||||
fields=null; // null means return all stored fields
|
||||
}
|
||||
}
|
||||
|
||||
int sz=docs.size();
|
||||
|
||||
writeMapOpener(includeScore ? 4 : 3);
|
||||
incLevel();
|
||||
writeKey("numFound",false);
|
||||
writeInt(null,docs.getNumFound());
|
||||
writeMapSeparator();
|
||||
writeKey("start",false);
|
||||
writeInt(null,docs.getStart());
|
||||
|
||||
if (includeScore) {
|
||||
writeMapSeparator();
|
||||
writeKey("maxScore",false);
|
||||
writeFloat(null,docs.getMaxScore());
|
||||
}
|
||||
writeMapSeparator();
|
||||
// indent();
|
||||
writeKey("docs",false);
|
||||
writeArrayOpener(sz);
|
||||
|
||||
incLevel();
|
||||
boolean first=true;
|
||||
|
||||
SolrIndexSearcher searcher = req.getSearcher();
|
||||
for (SolrDocument doc : docs) {
|
||||
|
||||
if (first) {
|
||||
first=false;
|
||||
} else {
|
||||
writeArraySeparator();
|
||||
}
|
||||
indent();
|
||||
writeSolrDocument(null, doc, fields, otherFields);
|
||||
}
|
||||
decLevel();
|
||||
writeArrayCloser();
|
||||
|
||||
if (otherFields !=null) {
|
||||
writeMap(null, otherFields, true, false);
|
||||
}
|
||||
|
||||
decLevel();
|
||||
indent();
|
||||
writeMapCloser();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Data structure tokens
|
||||
// NOTE: a positive size paramater indicates the number of elements
|
||||
|
|
|
@ -20,6 +20,8 @@ package org.apache.solr.request;
|
|||
import org.apache.lucene.document.Document;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.FastWriter;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.search.DocList;
|
||||
import java.io.IOException;
|
||||
|
@ -131,6 +133,8 @@ public abstract class TextResponseWriter {
|
|||
writeDouble(name, ((Double)val).doubleValue());
|
||||
} else if (val instanceof Document) {
|
||||
writeDoc(name, (Document)val, returnFields, 0.0f, false);
|
||||
} else if (val instanceof SolrDocument) {
|
||||
writeSolrDocument(name, (SolrDocument)val, returnFields, null);
|
||||
} else if (val instanceof DocList) {
|
||||
// requires access to IndexReader
|
||||
writeDocList(name, (DocList)val, returnFields,null);
|
||||
|
@ -139,6 +143,8 @@ public abstract class TextResponseWriter {
|
|||
// how do we know what fields to read?
|
||||
// todo: have a DocList/DocSet wrapper that
|
||||
// restricts the fields to write...?
|
||||
} else if (val instanceof SolrDocumentList) {
|
||||
writeSolrDocumentList(name, (SolrDocumentList)val, returnFields, null);
|
||||
} else if (val instanceof Map) {
|
||||
writeMap(name, (Map)val, false, true);
|
||||
} else if (val instanceof NamedList) {
|
||||
|
@ -161,8 +167,18 @@ public abstract class TextResponseWriter {
|
|||
|
||||
public abstract void writeDoc(String name, Document doc, Set<String> returnFields, float score, boolean includeScore) throws IOException;
|
||||
|
||||
/**
|
||||
* @since solr 1.3
|
||||
*/
|
||||
public abstract void writeSolrDocument(String name, SolrDocument doc, Set<String> returnFields, Map pseudoFields) throws IOException;
|
||||
|
||||
public abstract void writeDocList(String name, DocList ids, Set<String> fields, Map otherFields) throws IOException;
|
||||
|
||||
/**
|
||||
* @since solr 1.3
|
||||
*/
|
||||
public abstract void writeSolrDocumentList(String name, SolrDocumentList docs, Set<String> fields, Map otherFields) throws IOException;
|
||||
|
||||
public abstract void writeStr(String name, String val, boolean needsEscaping) throws IOException;
|
||||
|
||||
public abstract void writeMap(String name, Map val, boolean excludeOuter, boolean isFirstVal) throws IOException;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.apache.solr.request;
|
||||
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.XML;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
|
@ -333,7 +335,56 @@ final public class XMLWriter {
|
|||
writer.write("</doc>");
|
||||
}
|
||||
|
||||
public final void writeDocList(String name, DocList ids, Set<String> fields) throws IOException {
|
||||
/**
|
||||
* @since solr 1.3
|
||||
*/
|
||||
final void writeDoc(String name, SolrDocument doc, Set<String> returnFields, boolean includeScore) throws IOException {
|
||||
startTag("doc", name, false);
|
||||
incLevel();
|
||||
|
||||
if (includeScore) {
|
||||
writeVal("score", doc.getFirstValue("score"));
|
||||
}
|
||||
|
||||
for (String fname : doc.getFieldNames()) {
|
||||
Object val = doc.getFieldValue(fname);
|
||||
|
||||
if (val instanceof Collection) {
|
||||
writeVal(fname, val);
|
||||
} else {
|
||||
// single valued... figure out if we should put <arr> tags around it anyway
|
||||
SchemaField sf = schema.getFieldOrNull(fname);
|
||||
if (version>=2100 && sf!=null && sf.multiValued()) {
|
||||
startTag("arr",fname,false);
|
||||
doIndent=false;
|
||||
writeVal(fname, val);
|
||||
writer.write("</arr>");
|
||||
doIndent=defaultIndent;
|
||||
} else {
|
||||
writeVal(fname, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decLevel();
|
||||
if (doIndent) indent();
|
||||
writer.write("</doc>");
|
||||
}
|
||||
|
||||
|
||||
private static interface DocumentListInfo {
|
||||
Float getMaxScore();
|
||||
int getCount();
|
||||
int getNumFound();
|
||||
int getStart();
|
||||
void writeDocs( boolean includeScore, Set<String> fields ) throws IOException;
|
||||
}
|
||||
|
||||
private final void writeDocuments(
|
||||
String name,
|
||||
DocumentListInfo docs,
|
||||
Set<String> fields) throws IOException
|
||||
{
|
||||
boolean includeScore=false;
|
||||
if (fields!=null) {
|
||||
includeScore = fields.contains("score");
|
||||
|
@ -342,15 +393,15 @@ final public class XMLWriter {
|
|||
}
|
||||
}
|
||||
|
||||
int sz=ids.size();
|
||||
|
||||
int sz=docs.getCount();
|
||||
if (doIndent) indent();
|
||||
|
||||
writer.write("<result");
|
||||
writeAttr("name",name);
|
||||
writeAttr("numFound",Integer.toString(ids.matches()));
|
||||
writeAttr("start",Integer.toString(ids.offset()));
|
||||
if (includeScore) {
|
||||
writeAttr("maxScore",Float.toString(ids.maxScore()));
|
||||
writeAttr("numFound",Integer.toString(docs.getNumFound())); // TODO: change to long
|
||||
writeAttr("start",Integer.toString(docs.getStart())); // TODO: change to long
|
||||
if (includeScore && docs.getMaxScore()!=null) {
|
||||
writeAttr("maxScore",Float.toString(docs.getMaxScore()));
|
||||
}
|
||||
if (sz==0) {
|
||||
writer.write("/>");
|
||||
|
@ -360,17 +411,72 @@ final public class XMLWriter {
|
|||
}
|
||||
|
||||
incLevel();
|
||||
docs.writeDocs(includeScore, fields);
|
||||
decLevel();
|
||||
|
||||
if (doIndent) indent();
|
||||
writer.write("</result>");
|
||||
}
|
||||
|
||||
public final void writeSolrDocumentList(String name, final SolrDocumentList docs, Set<String> fields) throws IOException
|
||||
{
|
||||
this.writeDocuments( name, new DocumentListInfo()
|
||||
{
|
||||
public int getCount() {
|
||||
return docs.size();
|
||||
}
|
||||
|
||||
public Float getMaxScore() {
|
||||
return docs.getMaxScore();
|
||||
}
|
||||
|
||||
public int getNumFound() {
|
||||
return docs.getNumFound();
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return docs.getStart();
|
||||
}
|
||||
|
||||
public void writeDocs(boolean includeScore, Set<String> fields) throws IOException {
|
||||
for( SolrDocument doc : docs ) {
|
||||
writeDoc(null, doc, fields, includeScore);
|
||||
}
|
||||
}
|
||||
}, fields );
|
||||
}
|
||||
|
||||
public final void writeDocList(String name, final DocList ids, Set<String> fields) throws IOException
|
||||
{
|
||||
this.writeDocuments( name, new DocumentListInfo()
|
||||
{
|
||||
public int getCount() {
|
||||
return ids.size();
|
||||
}
|
||||
|
||||
public Float getMaxScore() {
|
||||
return ids.maxScore();
|
||||
}
|
||||
|
||||
public int getNumFound() {
|
||||
return ids.matches();
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return ids.offset();
|
||||
}
|
||||
|
||||
public void writeDocs(boolean includeScore, Set<String> fields) throws IOException {
|
||||
SolrIndexSearcher searcher = request.getSearcher();
|
||||
DocIterator iterator = ids.iterator();
|
||||
int sz = ids.size();
|
||||
for (int i=0; i<sz; i++) {
|
||||
int id = iterator.nextDoc();
|
||||
Document doc = searcher.doc(id, fields);
|
||||
writeDoc(null, doc, fields, (includeScore ? iterator.score() : 0.0f), includeScore);
|
||||
}
|
||||
decLevel();
|
||||
|
||||
if (doIndent) indent();
|
||||
writer.write("</result>");
|
||||
}
|
||||
}, fields );
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,7 +511,10 @@ final public class XMLWriter {
|
|||
} else if (val instanceof DocList) {
|
||||
// requires access to IndexReader
|
||||
writeDocList(name, (DocList)val, defaultFieldList);
|
||||
} else if (val instanceof DocSet) {
|
||||
}else if (val instanceof SolrDocumentList) {
|
||||
// requires access to IndexReader
|
||||
writeSolrDocumentList(name, (SolrDocumentList)val, defaultFieldList);
|
||||
}else if (val instanceof DocSet) {
|
||||
// how do we know what fields to read?
|
||||
// todo: have a DocList/DocSet wrapper that
|
||||
// restricts the fields to write...?
|
||||
|
|
Loading…
Reference in New Issue