diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 26ea96a2544..663ec6c8d43 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -194,6 +194,8 @@ Bug Fixes * SOLR-16808: Stop publishing environment variables via the Metrics API (Houston Putman) +* SOLR-16811: /update/json/docs?echo and mapUniqueKeyOnly params doesn't work (Mikhail Khludnev) + Dependency Upgrades --------------------- * PR#1494: Upgrade forbiddenapis to 3.5 (Uwe Schindler) diff --git a/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java b/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java index 868b88ddc30..82231d098cb 100644 --- a/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java +++ b/solr/core/src/java/org/apache/solr/handler/loader/JsonLoader.java @@ -295,10 +295,9 @@ public void handle(Map record, String path) { private Map getDocMap( Map record, JSONParser parser, String srcField, boolean mapUniqueKeyOnly) { - Map result = record; + Map result = mapUniqueKeyOnly ? record : new LinkedHashMap<>(record); if (srcField != null && parser instanceof RecordingJSONParser) { // if srcFIeld specified extract it out first - result = new LinkedHashMap<>(record); RecordingJSONParser rjp = (RecordingJSONParser) parser; result.put(srcField, rjp.getBuf()); rjp.resetBuf(); @@ -320,7 +319,9 @@ private Map getDocMap( if (srcField != null && result.containsKey(srcField)) { copy.put(srcField, result.remove(srcField)); } - copy.put(df, result.values()); + final List deepValues = new ArrayList<>(); + deepValues.addAll(result.values()); + copy.put(df, deepValues); result = copy; } diff --git a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java index e43bc486cec..f0be036bf9d 100644 --- a/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java +++ b/solr/core/src/test/org/apache/solr/handler/JsonLoaderTest.java @@ -16,6 +16,8 @@ */ package org.apache.solr.handler; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.UnaryOperator; @@ -23,6 +25,7 @@ import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputField; +import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ContentStreamBase; import org.apache.solr.common.util.Utils; import org.apache.solr.handler.loader.JsonLoader; @@ -300,25 +303,6 @@ public void testJsonDocFormat() throws Exception { assertEquals("v2", obj.get("f2")); assertTrue(obj.containsKey("f3")); - // TODO new test method - doc = "[{'id':'1'},{'id':'2'}]".replace('\'', '"'); - req = req("srcField", "_src_"); - req.getContext().put("path", "/update/json/docs"); - rsp = new SolrQueryResponse(); - p = new BufferingRequestProcessor(null); - loader = new JsonLoader(); - loader.load(req, rsp, new ContentStreamBase.StringStream(doc), p); - assertEquals(2, p.addCommands.size()); - - content = (String) p.addCommands.get(0).solrDoc.getFieldValue("_src_"); - assertNotNull(content); - obj = (Map) Utils.fromJSONString(content); - assertEquals("1", obj.get("id")); - content = (String) p.addCommands.get(1).solrDoc.getFieldValue("_src_"); - assertNotNull(content); - obj = (Map) Utils.fromJSONString(content); - assertEquals("2", obj.get("id")); - // TODO new test method String json = "{a:{" + "b:[{c:c1, e:e1},{c:c2, e :e2, d:{p:q}}]," + "x:y" + "}}"; req = req("split", "/|/a/b"); @@ -338,6 +322,115 @@ public void testJsonDocFormat() throws Exception { p.addCommands.get(0).solrDoc.toString()); } + public void testSrcAndUniqueDocs() throws Exception { + BufferingRequestProcessor p; + JsonLoader loader; + SolrQueryRequest req; + SolrQueryResponse rsp; + String doc; + String content; + Map src; + doc = "[{'id':'1','a':'b'},{'id':'2','c':'d'}]".replace('\'', '"'); + boolean idOnly = random().nextBoolean(); + boolean srcField = random().nextBoolean(); + ModifiableSolrParams params = new ModifiableSolrParams(); + if (idOnly) { + params.set("mapUniqueKeyOnly", "true"); + params.set("df", "_catch_all"); + } + if (srcField) { + params.set("srcField", "_src_"); + } + req = req(params); + req.getContext().put("path", "/update/json/docs"); + rsp = new SolrQueryResponse(); + p = new BufferingRequestProcessor(null); + loader = new JsonLoader(); + loader.load(req, rsp, new ContentStreamBase.StringStream(doc), p); + assertEquals(2, p.addCommands.size()); + + { + final SolrInputDocument doc1 = p.addCommands.get(0).solrDoc; + if (srcField) { + content = (String) doc1.getFieldValue("_src_"); + assertNotNull(content); + src = (Map) Utils.fromJSONString(content); + assertEquals("1", src.get("id")); + assertEquals("b", src.get("a")); + } else { + assertFalse(doc1.containsKey("_src_")); + } + assertEquals("1", doc1.getFieldValue("id")); + if (idOnly) { + assertEquals(Arrays.asList("1", "b"), new ArrayList<>(doc1.getFieldValues("_catch_all"))); + assertFalse(doc1.containsKey("a")); + } else { + assertEquals("b", doc1.getFieldValue("a")); + assertFalse(doc1.containsKey("_catch_all")); + } + } + { + final SolrInputDocument doc2 = p.addCommands.get(1).solrDoc; + if (srcField) { + content = (String) doc2.getFieldValue("_src_"); + assertNotNull(content); + src = (Map) Utils.fromJSONString(content); + assertEquals("2", src.get("id")); + assertEquals("d", src.get("c")); + } else { + assertFalse(doc2.containsKey("_src_")); + } + assertEquals("2", doc2.getFieldValue("id")); + if (idOnly) { + assertEquals(Arrays.asList("2", "d"), new ArrayList<>(doc2.getFieldValues("_catch_all"))); + assertFalse(doc2.containsKey("c")); + } else { + assertEquals("d", doc2.getFieldValue("c")); + assertFalse(doc2.containsKey("_catch_all")); + } + } + } + + public void testEchoDocs() throws Exception { + BufferingRequestProcessor p; + JsonLoader loader; + SolrQueryRequest req; + SolrQueryResponse rsp; + String doc; + + doc = "[{'id':'1'},{'id':'2'}]".replace('\'', '"'); + boolean src = random().nextBoolean(); + req = src ? req("srcField", "_src_", "echo", "true") : req("echo", "true"); + req.getContext().put("path", "/update/json/docs"); + rsp = new SolrQueryResponse(); + p = new BufferingRequestProcessor(null); + loader = new JsonLoader(); + loader.load(req, rsp, new ContentStreamBase.StringStream(doc), p); + assertEquals(0, p.addCommands.size()); + @SuppressWarnings("unchecked") + final List> docs = (List>) rsp.getValues().get("docs"); + assertNotNull(docs); + assertEquals(2, docs.size()); + { + Map doc1 = docs.get(0); + assertEquals("1", doc1.get("id")); + if (src) { + assertEquals("{\"id\":\"1\"}", doc1.get("_src_")); + } else { + assertFalse(doc1.containsKey("_src_")); + } + } + { + Map doc2 = docs.get(1); + assertEquals("2", doc2.get("id")); + if (src) { + assertEquals("{\"id\":\"2\"}", doc2.get("_src_")); + } else { + assertFalse(doc2.containsKey("_src_")); + } + } + } + private static final String PARENT_TWO_CHILDREN_JSON = "{\n" + " \"id\": \"1\",\n"