mirror of https://github.com/apache/lucene.git
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:
parent
269545dd91
commit
048d0e7bf4
|
@ -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
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue