aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/rendering
diff options
context:
space:
mode:
authorArne Juul <arnej@yahoo-inc.com>2018-06-15 10:37:10 +0200
committerArne Juul <arnej@yahoo-inc.com>2018-06-15 11:34:19 +0200
commita156ca38d3abf599a56d187238422820500902b5 (patch)
tree167d27998873c5b3d2547daa0a97e888b5fbacf9 /container-search/src/main/java/com/yahoo/search/rendering
parent88fd17919d10638cccd8efa71ed1916a855f88eb (diff)
render maps with string keys as JSON objects
* if structured data is an array of <key,value> objects, we prefer to render it as a JSON object since it is most likely a map in the document definition. * makes docsum rendering a closer match with document rendering and feed input format.
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/rendering')
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java46
1 files changed, 42 insertions, 4 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
index 55c846ccb5b..f8750e984a6 100644
--- a/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
+++ b/container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java
@@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.yahoo.data.JsonProducer;
import com.yahoo.data.access.Inspectable;
+import com.yahoo.data.access.Inspector;
+import com.yahoo.data.access.Type;
import com.yahoo.data.access.simple.JsonRender;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.StringFieldValue;
@@ -45,6 +47,7 @@ import com.yahoo.yolean.trace.TraceVisitor;
import org.json.JSONArray;
import org.json.JSONObject;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
@@ -313,6 +316,32 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
generator.writeFieldName(ROOT);
}
+ public String renderAsMap(Inspector data) throws IOException {
+ if (data.type() != Type.ARRAY) return null;
+ if (data.entryCount() == 0) return null;
+ ByteArrayOutputStream subStream = new ByteArrayOutputStream();
+ JsonGenerator subGenerator = generatorFactory.createGenerator(subStream, JsonEncoding.UTF8);
+ subGenerator.writeStartObject();
+ for (int i = 0; i < data.entryCount(); i++) {
+ Inspector obj = data.entry(i);
+ if (obj.type() != Type.OBJECT) return null;
+ if (obj.fieldCount() != 2) return null;
+ Inspector keyObj = obj.field("key");
+ if (keyObj.type() != Type.STRING) return null;
+
+ subGenerator.writeFieldName(keyObj.asString());
+
+ Inspector valueObj = obj.field("value");
+ if (! valueObj.valid()) return null;
+ StringBuilder intermediate = new StringBuilder();
+ JsonRender.render(valueObj, intermediate, true);
+ subGenerator.writeRawValue(intermediate.toString());
+ }
+ subGenerator.writeEndObject();
+ subGenerator.close();
+ return subStream.toString("UTF-8");
+ }
+
private void renderTiming() throws IOException {
if (!getResult().getQuery().getPresentation().getTiming()) return;
@@ -662,7 +691,7 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
* This instance is reused for all hits of a Result since we are in a single-threaded context
* and want to limit object creation.
*/
- private static class FieldConsumer implements Hit.RawUtf8Consumer {
+ private class FieldConsumer implements Hit.RawUtf8Consumer {
private final JsonGenerator generator;
private final boolean debugRendering;
@@ -741,6 +770,17 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
return true;
}
+ private void renderInspector(Inspector data) throws IOException {
+ String asMap = renderAsMap(data);
+ if (asMap != null) {
+ generator.writeRawValue(asMap);
+ } else {
+ StringBuilder intermediate = new StringBuilder();
+ JsonRender.render(data, intermediate, true);
+ generator.writeRawValue(intermediate.toString());
+ }
+ }
+
private void renderFieldContents(Object field) throws IOException {
if (field == null) {
generator.writeNull();
@@ -753,9 +793,7 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
} else if (field instanceof JsonProducer) {
generator.writeRawValue(((JsonProducer) field).toJson());
} else if (field instanceof Inspectable) {
- StringBuilder intermediate = new StringBuilder();
- JsonRender.render((Inspectable) field, intermediate, true);
- generator.writeRawValue(intermediate.toString());
+ renderInspector(((Inspectable)field).inspect());
} else if (field instanceof StringFieldValue) {
generator.writeString(((StringFieldValue)field).getString());
} else if (field instanceof TensorFieldValue) {