Author: ryan
Date: Tue Jan 8 13:15:19 2008
New Revision: 610156
URL: http://svn.apache.org/viewvc?rev=610156&view=rev
Log:
SOLR-446: TextResponseWriter can write SolrDocuments and SolrDocumentLists the
same way it writes Document and DocList.
Modified:
lucene/solr/trunk/CHANGES.txt
lucene/solr/trunk/src/java/org/apache/solr/request/JSONResponseWriter.java
lucene/solr/trunk/src/java/org/apache/solr/request/TextResponseWriter.java
lucene/solr/trunk/src/java/org/apache/solr/request/XMLWriter.java
Modified: lucene/solr/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/lucene/solr/trunk/CHANGES.txt?rev=610156&r1=610155&r2=610156&view=diff
==============================================================================
--- lucene/solr/trunk/CHANGES.txt (original)
+++ lucene/solr/trunk/CHANGES.txt Tue Jan 8 13:15:19 2008
@@ -181,6 +181,10 @@
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
Modified:
lucene/solr/trunk/src/java/org/apache/solr/request/JSONResponseWriter.java
URL:
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/request/JSONResponseWriter.java?rev=610156&r1=610155&r2=610156&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/request/JSONResponseWriter.java
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/request/JSONResponseWriter.java
Tue Jan 8 13:15:19 2008
@@ -19,6 +19,8 @@
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 @@
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);
@@ -456,6 +499,64 @@
indent();
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
Modified:
lucene/solr/trunk/src/java/org/apache/solr/request/TextResponseWriter.java
URL:
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/request/TextResponseWriter.java?rev=610156&r1=610155&r2=610156&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/request/TextResponseWriter.java
(original)
+++ lucene/solr/trunk/src/java/org/apache/solr/request/TextResponseWriter.java
Tue Jan 8 13:15:19 2008
@@ -20,6 +20,8 @@
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 @@
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 @@
// 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,7 +167,17 @@
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;
Modified: lucene/solr/trunk/src/java/org/apache/solr/request/XMLWriter.java
URL:
http://svn.apache.org/viewvc/lucene/solr/trunk/src/java/org/apache/solr/request/XMLWriter.java?rev=610156&r1=610155&r2=610156&view=diff
==============================================================================
--- lucene/solr/trunk/src/java/org/apache/solr/request/XMLWriter.java (original)
+++ lucene/solr/trunk/src/java/org/apache/solr/request/XMLWriter.java Tue Jan
8 13:15:19 2008
@@ -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 @@
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");
@@ -341,16 +392,16 @@
fields=null; // null means return all stored fields
}
}
-
- 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,18 +411,73 @@
}
incLevel();
- SolrIndexSearcher searcher = request.getSearcher();
- DocIterator iterator = ids.iterator();
- 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);
- }
+ 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);
+ }
+ }
+ }, fields );
+ }
public void writeVal(String name, Object val) throws IOException {
@@ -405,7 +511,10 @@
} 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...?