首先,在结构化mapping之前,我们需要获取到mapping的字符串。
ImmutableOpenMap<String, MappingMetaData> mappings = client.admin().cluster().prepareState().execute()
.actionGet().getState().getMetaData().getIndices().get(index).getMappings();
String source = mappings.get(type).source().toString();
然后有了这个source之后,就可以看看如何解析它的结构。
首先我创建了一个多叉树如下:
public class MultiTreeNode {
private MultiTreeNode preNode;
private List<String> values;
private List<MultiTreeNode> sonNodeLst;
public MultiTreeNode() {
this.values = Lists.newArrayList();
this.sonNodeLst = Lists.newArrayList();
}
public List<String> getValues() {
return values;
}
public void addValues(String value) {
this.values.add(value);
}
public MultiTreeNode getPreNode() {
return preNode;
}
public void setPreNode(MultiTreeNode preNode) {
this.preNode = preNode;
}
public List<MultiTreeNode> getSonNodeLst() {
return sonNodeLst;
}
public void setSonNodeLst(List<MultiTreeNode> sonNodeLst) {
this.sonNodeLst = sonNodeLst;
}
public void addSonNodeLst(MultiTreeNode node) {
this.sonNodeLst.add(node);
}
public int getSize() {
return this.sonNodeLst.size();
}
}
以下面的这个mapping json为例
(后面补个图)
知道如何解析结构后,我就写了一个递归方法去生成这么一个树的对象
public MultiTreeNode assembleData(String source, int beginIndex, int endIndex, boolean flag, int saveFlag,
String accCharacter, MultiTreeNode currentNode) throws Exception{
try{
if (0 == beginIndex) {
flag = false;
}
String s = source.substring(beginIndex, endIndex);
if (("\"").equals(s)) {
flag = !flag;
saveFlag++;
} else if (flag) {
accCharacter += s;
}
if (2 == saveFlag) {
saveFlag = 0;
currentNode.addValues(accCharacter);
accCharacter = "";
}
if (("{").equals(s)) {
MultiTreeNode sonNode = new MultiTreeNode();
sonNode.setPreNode(currentNode);
currentNode.addSonNodeLst(sonNode);
currentNode = currentNode.getSonNodeLst().get(currentNode.getSize() - 1);
} else if (("}").equals(s)) {
currentNode = currentNode.getPreNode();
}
if ((source.length() - 2) == beginIndex) {
return currentNode;
}
this.assembleData(source, ++beginIndex, ++endIndex, flag, saveFlag, accCharacter, currentNode);
return currentNode;
}catch(Exception e){
e.printStackTrace();
throw e;
}
}
当我们获取到这个返回的根节点对象时,我们就能运用一开始那个设计的结构去遍历这颗树。
因为我的设计的原因,我的起始遍历节点是为type下的子节点也就是properties开始,所以还需要这段操作
root = root.getSonNodeLst().get(0);
private void forEachMappingsTree(MultiTreeNode currentNode, int i,String preName) {
List<MultiTreeNode> sonNodeLst = currentNode.getSonNodeLst();
MultiTreeNode currentSonNode = sonNodeLst.get(0);
List<String> currentvalues = currentSonNode.getValues();
MultiTreeNode nextSonNode = currentSonNode.getSonNodeLst().get(i);
List<String> nextValues = nextSonNode.getValues();
if (null != nextSonNode && !"properties".equals(nextValues.get(0))) {
System.out.println(preName + currentvalues.get(i));
} else {
preName=preName+currentvalues.get(i)+".";
this.forEachMappingsTree(nextSonNode, 0,preName);
preName="";
}
if (i < currentvalues.size() - 1) {
this.forEachMappingsTree(currentNode, i + 1,preName);
}
if (i >= currentvalues.size() - 1) {
return;
}
}
然后可以根据我们想要的逻辑,在合适的位置和节点进行操作。