SOLR-6617

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1631649 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Noble Paul 2014-10-14 07:21:26 +00:00
parent 269545dd91
commit 048d0e7bf4
4 changed files with 63 additions and 13 deletions

View File

@ -89,6 +89,11 @@ Upgrading from Solr 4.x
for "createcollection", "delete" for "removecollection" and "deleteshard" for for "createcollection", "delete" for "removecollection" and "deleteshard" for
"removeshard". "removeshard".
* If you have been using the /update/json/docs to index documents, SOLR-6617 introduces
backward incompatible change. the key names created are fully qualified paths of keys .
If you need the old functionality back , please add an extra parameter f=/**
example: /update/json/docs?f=/**
Detailed Change List Detailed Change List
---------------------- ----------------------
@ -159,6 +164,11 @@ New Features
* SOLR-6605: Make ShardHandlerFactory maxConnections configurable. * SOLR-6605: Make ShardHandlerFactory maxConnections configurable.
(Christine Poerschke via shalin) (Christine Poerschke via shalin)
* SOLR-6585: RequestHandlers can optionaly handle sub paths as well (Noble Paul)
* SOLR-6617: /update/json/docs path will use fully qualified node names by default
(NOble Paul)
Bug Fixes Bug Fixes
---------------------- ----------------------
@ -443,7 +453,6 @@ New Features
* SOLR-6233: Provide basic command line tools for checking Solr status and health. * SOLR-6233: Provide basic command line tools for checking Solr status and health.
(Timothy Potter) (Timothy Potter)
* SOLR-6585: RequestHandlers can optionaly handle sub paths as well (Noble Paul)
Bug Fixes Bug Fixes
---------------------- ----------------------

View File

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.params.SolrParams;
@ -191,7 +192,7 @@ public class JsonLoader extends ContentStreamLoader {
private void handleSplitMode(String split, String[] fields) throws IOException { private void handleSplitMode(String split, String[] fields) throws IOException {
if(split == null) split = "/"; if(split == null) split = "/";
if(fields == null || fields.length ==0) fields = new String[]{"/**"}; if(fields == null || fields.length ==0) fields = new String[]{"$FQN:/**"};
final boolean echo = "true".equals( req.getParams().get("echo")); final boolean echo = "true".equals( req.getParams().get("echo"));
JsonRecordReader jsonRecordReader = JsonRecordReader.getInst(split, Arrays.asList(fields)); JsonRecordReader jsonRecordReader = JsonRecordReader.getInst(split, Arrays.asList(fields));
jsonRecordReader.streamRecords(parser,new JsonRecordReader.Handler() { jsonRecordReader.streamRecords(parser,new JsonRecordReader.Handler() {
@ -222,7 +223,7 @@ public class JsonLoader extends ContentStreamLoader {
}); });
} }
private void handleStreamingSingleDocs() throws IOException /*private void handleStreamingSingleDocs() throws IOException
{ {
while( true ) { while( true ) {
int ev = parser.nextEvent(); int ev = parser.nextEvent();
@ -240,7 +241,7 @@ public class JsonLoader extends ContentStreamLoader {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unexpected event :"+ev); throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unexpected event :"+ev);
} }
} }
} }*/
// //
// "delete":"id" // "delete":"id"

View File

@ -29,6 +29,7 @@ import static org.noggit.JSONParser.*;
*/ */
public class JsonRecordReader { public class JsonRecordReader {
public static final String DELIM = ".";
private Node rootNode = new Node("/", (Node)null); private Node rootNode = new Node("/", (Node)null);
@ -159,6 +160,7 @@ public class JsonRecordReader {
boolean isRecord = false; //flag: this Node starts a new record boolean isRecord = false; //flag: this Node starts a new record
Node wildCardChild ; Node wildCardChild ;
Node recursiveWildCardChild; Node recursiveWildCardChild;
private boolean useFqn = false;
public Node(String name, Node p) { public Node(String name, Node p) {
@ -233,6 +235,10 @@ public class JsonRecordReader {
// path with content we want to store and return // path with content we want to store and return
n.isLeaf = true; // we have to store text found here n.isLeaf = true; // we have to store text found here
n.fieldName = fieldName; // name to store collected text against n.fieldName = fieldName; // name to store collected text against
if("$FQN".equals(n.fieldName)) {
n.fieldName = null;
n.useFqn = true;
}
} }
} else { } else {
//wildcards must only come at the end //wildcards must only come at the end
@ -278,13 +284,13 @@ public class JsonRecordReader {
event = parser.nextEvent(); event = parser.nextEvent();
if(event == EOF) break; if(event == EOF) break;
if (event == OBJECT_START) { if (event == OBJECT_START) {
handleObjectStart(parser, new HashSet<Node>(), handler, values, stack, recordStarted); handleObjectStart(parser, new HashSet<Node>(), handler, values, stack, recordStarted, null);
} else if (event == ARRAY_START) { } else if (event == ARRAY_START) {
for (; ; ) { for (; ; ) {
event = parser.nextEvent(); event = parser.nextEvent();
if (event == ARRAY_END) break; if (event == ARRAY_END) break;
if (event == OBJECT_START) { if (event == OBJECT_START) {
handleObjectStart(parser, new HashSet<Node>(), handler, values, stack, recordStarted); handleObjectStart(parser, new HashSet<Node>(), handler, values, stack, recordStarted,null);
} }
} }
} }
@ -306,7 +312,8 @@ public class JsonRecordReader {
*/ */
private void handleObjectStart(final JSONParser parser, final Set<Node> childrenFound, private void handleObjectStart(final JSONParser parser, final Set<Node> childrenFound,
final Handler handler, final Map<String, Object> values, final Handler handler, final Map<String, Object> values,
final Stack<Set<String>> stack, boolean recordStarted) final Stack<Set<String>> stack, boolean recordStarted,
MethodFrameWrapper frameWrapper)
throws IOException { throws IOException {
final boolean isRecordStarted = recordStarted || isRecord; final boolean isRecordStarted = recordStarted || isRecord;
@ -324,20 +331,22 @@ public class JsonRecordReader {
} }
class Wrapper extends MethodFrameWrapper { class Wrapper extends MethodFrameWrapper {
Wrapper( Node node) { Wrapper(Node node, MethodFrameWrapper parent, String name) {
this.node = node; this.node = node;
this.parent= parent;
this.name = name;
} }
@Override @Override
public void walk(int event) throws IOException { public void walk(int event) throws IOException {
if (event == OBJECT_START) { if (event == OBJECT_START) {
node.handleObjectStart(parser, childrenFound, handler, values, stack, isRecordStarted); node.handleObjectStart(parser, childrenFound, handler, values, stack, isRecordStarted, this);
} else if (event == ARRAY_START) { } else if (event == ARRAY_START) {
for (; ; ) { for (; ; ) {
event = parser.nextEvent(); event = parser.nextEvent();
if (event == ARRAY_END) break; if (event == ARRAY_END) break;
if (event == OBJECT_START) { if (event == OBJECT_START) {
node.handleObjectStart(parser, childrenFound, handler, values, stack, isRecordStarted); node.handleObjectStart(parser, childrenFound, handler, values, stack, isRecordStarted,this);
} }
} }
} }
@ -365,10 +374,10 @@ public class JsonRecordReader {
if (node != null) { if (node != null) {
if (node.isLeaf) {//this is a leaf collect data here if (node.isLeaf) {//this is a leaf collect data here
event = parser.nextEvent(); event = parser.nextEvent();
String nameInRecord = node.fieldName == null ? name : node.fieldName; String nameInRecord = node.fieldName == null ? getNameInRecord(name, frameWrapper, node) : node.fieldName;
MethodFrameWrapper runnable = null; MethodFrameWrapper runnable = null;
if(event == OBJECT_START || event == ARRAY_START){ if(event == OBJECT_START || event == ARRAY_START){
if(node.recursiveWildCardChild !=null) runnable = new Wrapper(node); if(node.recursiveWildCardChild !=null) runnable = new Wrapper(node, frameWrapper,name);
} }
Object val = parseSingleFieldValue(event, parser, runnable); Object val = parseSingleFieldValue(event, parser, runnable);
if(val !=null) { if(val !=null) {
@ -378,7 +387,7 @@ public class JsonRecordReader {
} else { } else {
event = parser.nextEvent(); event = parser.nextEvent();
new Wrapper(node).walk(event); new Wrapper(node, frameWrapper, name).walk(event);
} }
} else { } else {
//this is not something we are interested in . skip it //this is not something we are interested in . skip it
@ -413,6 +422,13 @@ public class JsonRecordReader {
} }
} }
private String getNameInRecord(String name,MethodFrameWrapper frameWrapper, Node n) {
if(frameWrapper == null || !n.useFqn) return name;
StringBuilder sb = new StringBuilder();
frameWrapper.prependName(sb);
return sb.append(DELIM).append(name).toString();
}
private boolean isRecord() { private boolean isRecord() {
return isRecord; return isRecord;
} }
@ -521,6 +537,16 @@ public class JsonRecordReader {
} }
static abstract class MethodFrameWrapper { static abstract class MethodFrameWrapper {
Node node; Node node;
MethodFrameWrapper parent;
String name;
void prependName(StringBuilder sb){
if(parent !=null) {
parent.prependName(sb);
sb.append(DELIM);
}
sb.append(name);
}
public abstract void walk(int event) throws IOException; public abstract void walk(int event) throws IOException;
} }

View File

@ -181,7 +181,21 @@ public class TestJsonRecordReader extends SolrTestCaseJ4 {
assertEquals(2, records.size()); assertEquals(2, records.size());
for (Map<String, Object> record : records) { for (Map<String, Object> record : records) {
assertEquals(6,record.size()); assertEquals(6,record.size());
assertTrue(record.containsKey("subject"));
assertTrue(record.containsKey("test"));
assertTrue(record.containsKey("marks"));
} }
streamer = JsonRecordReader.getInst("/exams", Collections.singletonList("$FQN:/**"));
records = streamer.getAllRecords(new StringReader(json));
assertEquals(2, records.size());
for (Map<String, Object> record : records) {
assertEquals(6,record.size());
assertTrue(record.containsKey("exams.subject"));
assertTrue(record.containsKey("exams.test"));
assertTrue(record.containsKey("exams.marks"));
}
streamer = JsonRecordReader.getInst("/", Collections.singletonList("txt:/**")); streamer = JsonRecordReader.getInst("/", Collections.singletonList("txt:/**"));
records = streamer.getAllRecords(new StringReader(json)); records = streamer.getAllRecords(new StringReader(json));
assertEquals(1, records.size()); assertEquals(1, records.size());