diff --git a/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java b/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java index eaff2d1cbd2..a1dd38bdfae 100644 --- a/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java +++ b/solr/solrj/src/java/org/apache/solr/common/util/JsonRecordReader.java @@ -98,7 +98,7 @@ public class JsonRecordReader { if ("".equals(paths.get(0).trim())) paths.remove(0); rootNode.build(paths, fieldName, multiValued, isRecord, path); -// rootNode.buildOptimise(null); + rootNode.buildOptimize(); } /** @@ -154,8 +154,6 @@ public class JsonRecordReader { String fieldName; // the fieldname in the emitted record (key of the map) String splitPath; // the full path from the forEach entity attribute final LinkedHashMap childNodes = new LinkedHashMap<>(); // List of immediate child Nodes of this node - List wildCardNodes; // List of '//' style decendants of this Node - Node wildAncestor; // ancestor Node containing '//' style decendants Node parent; // parent Node in the tree boolean isLeaf = false; // flag: store/emit streamed text for this node boolean isRecord = false; //flag: this Node starts a new record @@ -179,14 +177,13 @@ public class JsonRecordReader { /** * Walk the Node tree propagating any wildDescentant information to - * child nodes. This allows us to optimise the performance of the - * main getInst method. + * child nodes. */ - private void buildOptimise(Node wa) { - wildAncestor = wa; - if (wildCardNodes != null) wa = this; - if (childNodes != null) - for (Node n : childNodes.values()) n.buildOptimise(wa); + private void buildOptimize() { + if(parent != null && parent.recursiveWildCardChild !=null && this.recursiveWildCardChild ==null){ + this.recursiveWildCardChild = parent.recursiveWildCardChild; + } + for (Node n : childNodes.values()) n.buildOptimize(); } static final String WILDCARD_PATH = "*"; static final String RECURSIVE_WILDCARD_PATH = "**"; @@ -259,7 +256,7 @@ public class JsonRecordReader { * deep-copied for thread safety */ private static Map getDeepCopy(Map values) { - Map result = new HashMap<>(); + Map result = new LinkedHashMap<>(); for (Map.Entry entry : values.entrySet()) { if (entry.getValue() instanceof List) { result.put(entry.getKey(), new ArrayList((List) entry.getValue())); diff --git a/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java b/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java index 30f714e9920..05b9fc7ee28 100644 --- a/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java +++ b/solr/solrj/src/test/org/apache/solr/common/util/TestJsonRecordReader.java @@ -156,4 +156,37 @@ public class TestJsonRecordReader extends SolrTestCaseJ4 { } + public void testRecursiveWildcard2() throws Exception{ + String json = "{\n" + + " \"first\": \"John\",\n" + + " \"last\": \"Doe\",\n" + + " \"grade\": 8,\n" + + " \"exams\": [\n" + + " {\n" + + " \"subject\": \"Maths\",\n" + + " \"test\" : \"term1\",\n" + + " \"marks\":90},\n" + + " {\n" + + " \"subject\": \"Biology\",\n" + + " \"test\" : \"term1\",\n" + + " \"marks\":86}\n" + + " ]\n" + + "}"; + + JsonRecordReader streamer; + List> records; + + streamer = JsonRecordReader.getInst("/exams", Collections.singletonList("/**")); + records = streamer.getAllRecords(new StringReader(json)); + assertEquals(2, records.size()); + for (Map record : records) { + assertEquals(6,record.size()); + } + streamer = JsonRecordReader.getInst("/", Collections.singletonList("txt:/**")); + records = streamer.getAllRecords(new StringReader(json)); + assertEquals(1, records.size()); + assertEquals(9, ((List)records.get(0).get("txt")).size() ); + + } + }