summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--container-search/src/main/java/com/yahoo/search/rendering/JsonRenderer.java37
-rw-r--r--container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java48
2 files changed, 81 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..7d60d7cf9ee 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,7 +9,10 @@ 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.data.access.simple.Value;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.StringFieldValue;
import com.yahoo.document.datatypes.TensorFieldValue;
@@ -741,6 +744,34 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
return true;
}
+ private static Inspector wrapAsMap(Inspector data) {
+ if (data.type() != Type.ARRAY) return null;
+ if (data.entryCount() == 0) return null;
+ Value.ObjectValue map = new Value.ObjectValue();
+ 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 key = obj.field("key");
+ Inspector value = obj.field("value");
+ if (key.type() != Type.STRING) return null;
+ if (! value.valid()) return null;
+ map.put(key.asString(), value);
+ }
+ return map;
+ }
+
+ private void renderInspector(Inspector data) throws IOException {
+ StringBuilder intermediate = new StringBuilder();
+ Inspector asMap = wrapAsMap(data);
+ if (asMap != null) {
+ JsonRender.render(asMap, intermediate, true);
+ } else {
+ JsonRender.render(data, intermediate, true);
+ }
+ generator.writeRawValue(intermediate.toString());
+ }
+
private void renderFieldContents(Object field) throws IOException {
if (field == null) {
generator.writeNull();
@@ -750,12 +781,10 @@ public class JsonRenderer extends AsynchronousSectionedRenderer<Result> {
generator.writeTree((TreeNode) field);
} else if (field instanceof Tensor) {
renderTensor(Optional.of((Tensor)field));
+ } else if (field instanceof Inspectable) {
+ renderInspector(((Inspectable)field).inspect());
} 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());
} else if (field instanceof StringFieldValue) {
generator.writeString(((StringFieldValue)field).getString());
} else if (field instanceof TensorFieldValue) {
diff --git a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
index bf56ad19f44..caad1c76362 100644
--- a/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/rendering/JsonRendererTestCase.java
@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.ListenableFuture;
import com.yahoo.component.chain.Chain;
+import com.yahoo.data.access.simple.Value;
import com.yahoo.data.access.slime.SlimeAdapter;
import com.yahoo.document.DataType;
import com.yahoo.document.DocumentId;
@@ -1111,6 +1112,53 @@ public class JsonRendererTestCase {
}
@Test
+ public final void testMapInField() throws IOException, InterruptedException, ExecutionException, JSONException {
+ String expected = "{\n"
+ + " \"root\": {\n"
+ + " \"children\": [\n"
+ + " {\n"
+ + " \"fields\": {\n"
+ + " \"structured\": {\n"
+ + " \"foo\": \"string foo\",\n"
+ + " \"bar\": [\"array bar elem 1\", \"array bar elem 2\"],\n"
+ + " \"baz\": {\"f1\": \"object baz field 1\", \"f2\": \"object baz field 2\"}\n"
+ + " }\n"
+ + " },\n"
+ + " \"id\": \"MapInField\",\n"
+ + " \"relevance\": 1.0\n"
+ + " }\n"
+ + " ],\n"
+ + " \"fields\": {\n"
+ + " \"totalCount\": 1\n"
+ + " },\n"
+ + " \"id\": \"toplevel\",\n"
+ + " \"relevance\": 1.0\n"
+ + " }\n"
+ + "}\n";
+ Result r = newEmptyResult();
+ Hit h = new Hit("MapInField");
+ Value.ArrayValue atop = new Value.ArrayValue();
+ atop.add(new Value.ObjectValue()
+ .put("key", new Value.StringValue("foo"))
+ .put("value", new Value.StringValue("string foo")))
+ .add(new Value.ObjectValue()
+ .put("key", new Value.StringValue("bar"))
+ .put("value", new Value.ArrayValue()
+ .add(new Value.StringValue("array bar elem 1"))
+ .add(new Value.StringValue("array bar elem 2"))))
+ .add(new Value.ObjectValue()
+ .put("key", new Value.StringValue("baz"))
+ .put("value", new Value.ObjectValue()
+ .put("f1", new Value.StringValue("object baz field 1"))
+ .put("f2", new Value.StringValue("object baz field 2"))));
+ h.setField("structured", atop);
+ r.hits().add(h);
+ r.setTotalHitCount(1L);
+ String summary = render(r);
+ assertEqualJson(expected, summary);
+ }
+
+ @Test
public void testThatTheJsonValidatorCanCatchErrors() {
String json = "{"
+ " \"root\": {"