intial support for pluggable type mappers
This commit is contained in:
parent
b799b7a9d7
commit
f560383b53
|
@ -19,27 +19,24 @@
|
|||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.node.ArrayNode;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.MapBuilder;
|
||||
import org.elasticsearch.util.io.FastStringReader;
|
||||
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
|
||||
import org.elasticsearch.util.joda.Joda;
|
||||
import org.elasticsearch.util.json.Jackson;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.collect.Lists.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
|
||||
/**
|
||||
|
@ -51,8 +48,36 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
|
||||
private final AnalysisService analysisService;
|
||||
|
||||
private final JsonObjectTypeParser rootObjectTypeParser = new JsonObjectTypeParser();
|
||||
|
||||
private final Object typeParsersMutex = new Object();
|
||||
|
||||
private volatile ImmutableMap<String, JsonTypeParser> typeParsers;
|
||||
|
||||
public JsonDocumentMapperParser(AnalysisService analysisService) {
|
||||
this.analysisService = analysisService;
|
||||
typeParsers = new MapBuilder<String, JsonTypeParser>()
|
||||
.put(JsonShortFieldMapper.JSON_TYPE, new JsonShortTypeParser())
|
||||
.put(JsonIntegerFieldMapper.JSON_TYPE, new JsonIntegerTypeParser())
|
||||
.put(JsonLongFieldMapper.JSON_TYPE, new JsonLongTypeParser())
|
||||
.put(JsonFloatFieldMapper.JSON_TYPE, new JsonFloatTypeParser())
|
||||
.put(JsonDoubleFieldMapper.JSON_TYPE, new JsonDoubleTypeParser())
|
||||
.put(JsonBooleanFieldMapper.JSON_TYPE, new JsonBooleanTypeParser())
|
||||
.put(JsonBinaryFieldMapper.JSON_TYPE, new JsonBinaryTypeParser())
|
||||
.put(JsonDateFieldMapper.JSON_TYPE, new JsonDateTypeParser())
|
||||
.put(JsonStringFieldMapper.JSON_TYPE, new JsonStringTypeParser())
|
||||
.put(JsonObjectMapper.JSON_TYPE, new JsonObjectTypeParser())
|
||||
.put(JsonMultiFieldMapper.JSON_TYPE, new JsonMultiFieldTypeParser())
|
||||
.immutableMap();
|
||||
}
|
||||
|
||||
public void putTypeParser(String type, JsonTypeParser typeParser) {
|
||||
synchronized (typeParsersMutex) {
|
||||
typeParsers = new MapBuilder<String, JsonTypeParser>()
|
||||
.putAll(typeParsers)
|
||||
.put(type, typeParser)
|
||||
.immutableMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public DocumentMapper parse(String source) throws MapperParsingException {
|
||||
|
@ -86,7 +111,9 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
}
|
||||
}
|
||||
|
||||
JsonDocumentMapper.Builder docBuilder = JsonMapperBuilders.doc(parseObject(type, rootObj));
|
||||
JsonTypeParser.ParserContext parserContext = new JsonTypeParser.ParserContext(rootObj, analysisService, typeParsers);
|
||||
|
||||
JsonDocumentMapper.Builder docBuilder = doc((JsonObjectMapper.Builder) rootObjectTypeParser.parse(type, rootObj, parserContext));
|
||||
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = rootObj.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
|
@ -94,17 +121,17 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
JsonNode fieldNode = entry.getValue();
|
||||
|
||||
if (JsonSourceFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.sourceField(parseSourceField((ObjectNode) fieldNode));
|
||||
docBuilder.sourceField(parseSourceField((ObjectNode) fieldNode, parserContext));
|
||||
} else if (JsonIdFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.idField(parseIdField((ObjectNode) fieldNode));
|
||||
docBuilder.idField(parseIdField((ObjectNode) fieldNode, parserContext));
|
||||
} else if (JsonTypeFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.typeField(parseTypeField((ObjectNode) fieldNode));
|
||||
docBuilder.typeField(parseTypeField((ObjectNode) fieldNode, parserContext));
|
||||
} else if (JsonUidFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.uidField(parseUidField((ObjectNode) fieldNode));
|
||||
docBuilder.uidField(parseUidField((ObjectNode) fieldNode, parserContext));
|
||||
} else if (JsonBoostFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.boostField(parseBoostField((ObjectNode) fieldNode));
|
||||
docBuilder.boostField(parseBoostField((ObjectNode) fieldNode, parserContext));
|
||||
} else if (JsonAllFieldMapper.JSON_TYPE.equals(fieldName)) {
|
||||
docBuilder.allField(parseAllField((ObjectNode) fieldNode));
|
||||
docBuilder.allField(parseAllField((ObjectNode) fieldNode, parserContext));
|
||||
} else if ("indexAnalyzer".equals(fieldName)) {
|
||||
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.getTextValue()));
|
||||
} else if ("searchAnalyzer".equals(fieldName)) {
|
||||
|
@ -130,7 +157,7 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
return documentMapper;
|
||||
}
|
||||
|
||||
private JsonUidFieldMapper.Builder parseUidField(ObjectNode uidNode) {
|
||||
private JsonUidFieldMapper.Builder parseUidField(ObjectNode uidNode, JsonTypeParser.ParserContext parserContext) {
|
||||
// String name = uidNode.get("name") == null ? JsonUidFieldMapper.Defaults.NAME : uidNode.get("name").getTextValue();
|
||||
JsonUidFieldMapper.Builder builder = uid();
|
||||
// for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = uidNode.getFields(); fieldsIt.hasNext();) {
|
||||
|
@ -145,10 +172,10 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private JsonBoostFieldMapper.Builder parseBoostField(ObjectNode boostNode) {
|
||||
private JsonBoostFieldMapper.Builder parseBoostField(ObjectNode boostNode, JsonTypeParser.ParserContext parserContext) {
|
||||
String name = boostNode.get("name") == null ? JsonBoostFieldMapper.Defaults.NAME : boostNode.get("name").getTextValue();
|
||||
JsonBoostFieldMapper.Builder builder = boost(name);
|
||||
parseNumberField(builder, name, boostNode);
|
||||
parseNumberField(builder, name, boostNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = boostNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
|
@ -160,25 +187,25 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private JsonTypeFieldMapper.Builder parseTypeField(ObjectNode typeNode) {
|
||||
private JsonTypeFieldMapper.Builder parseTypeField(ObjectNode typeNode, JsonTypeParser.ParserContext parserContext) {
|
||||
// String name = typeNode.get("name") == null ? JsonTypeFieldMapper.Defaults.NAME : typeNode.get("name").getTextValue();
|
||||
JsonTypeFieldMapper.Builder builder = type();
|
||||
parseJsonField(builder, builder.name, typeNode);
|
||||
parseJsonField(builder, builder.name, typeNode, parserContext);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private JsonIdFieldMapper.Builder parseIdField(ObjectNode idNode) {
|
||||
private JsonIdFieldMapper.Builder parseIdField(ObjectNode idNode, JsonTypeParser.ParserContext parserContext) {
|
||||
// String name = idNode.get("name") == null ? JsonIdFieldMapper.Defaults.NAME : idNode.get("name").getTextValue();
|
||||
JsonIdFieldMapper.Builder builder = id();
|
||||
parseJsonField(builder, builder.name, idNode);
|
||||
parseJsonField(builder, builder.name, idNode, parserContext);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonAllFieldMapper.Builder parseAllField(ObjectNode allNode) {
|
||||
private JsonAllFieldMapper.Builder parseAllField(ObjectNode allNode, JsonTypeParser.ParserContext parserContext) {
|
||||
// String name = idNode.get("name") == null ? JsonIdFieldMapper.Defaults.NAME : idNode.get("name").getTextValue();
|
||||
JsonAllFieldMapper.Builder builder = all();
|
||||
parseJsonField(builder, builder.name, allNode);
|
||||
parseJsonField(builder, builder.name, allNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = allNode.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
String fieldName = entry.getKey();
|
||||
|
@ -190,7 +217,7 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
return builder;
|
||||
}
|
||||
|
||||
private JsonSourceFieldMapper.Builder parseSourceField(ObjectNode sourceNode) {
|
||||
private JsonSourceFieldMapper.Builder parseSourceField(ObjectNode sourceNode, JsonTypeParser.ParserContext parserContext) {
|
||||
// String name = sourceNode.get("name") == null ? JsonSourceFieldMapper.Defaults.NAME : sourceNode.get("name").getTextValue();
|
||||
JsonSourceFieldMapper.Builder builder = source();
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = sourceNode.getFields(); fieldsIt.hasNext();) {
|
||||
|
@ -217,360 +244,4 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
|||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonObjectMapper.Builder parseObject(String name, ObjectNode node) {
|
||||
JsonObjectMapper.Builder builder = object(name);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = node.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
String fieldName = entry.getKey();
|
||||
JsonNode fieldNode = entry.getValue();
|
||||
if (fieldName.equals("dynamic")) {
|
||||
builder.dynamic(nodeBooleanValue(fieldNode));
|
||||
} else if (fieldName.equals("type")) {
|
||||
String type = fieldNode.getTextValue();
|
||||
if (!type.equals("object")) {
|
||||
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
|
||||
}
|
||||
} else if (fieldName.equals("dateFormats")) {
|
||||
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
||||
if (fieldNode.isArray()) {
|
||||
for (JsonNode node1 : (ArrayNode) fieldNode) {
|
||||
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
|
||||
}
|
||||
} else if ("none".equals(fieldNode.getValueAsText())) {
|
||||
dateTimeFormatters = null;
|
||||
} else {
|
||||
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
|
||||
}
|
||||
if (dateTimeFormatters == null) {
|
||||
builder.noDateTimeFormatter();
|
||||
} else {
|
||||
builder.dateTimeFormatter(dateTimeFormatters);
|
||||
}
|
||||
} else if (fieldName.equals("enabled")) {
|
||||
builder.enabled(nodeBooleanValue(fieldNode));
|
||||
} else if (fieldName.equals("pathType")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
|
||||
} else if (fieldName.equals("properties")) {
|
||||
parseProperties(builder, (ObjectNode) fieldNode);
|
||||
} else if (fieldName.equals("includeInAll")) {
|
||||
builder.includeInAll(nodeBooleanValue(fieldNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonPath.Type parsePathType(String name, String path) throws MapperParsingException {
|
||||
if ("justName".equals(path) || "just_name".equals(path)) {
|
||||
return JsonPath.Type.JUST_NAME;
|
||||
} else if ("full".equals(path)) {
|
||||
return JsonPath.Type.FULL;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for pathType [" + path + "] for objet [" + name + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseProperties(JsonObjectMapper.Builder objBuilder, ObjectNode propsNode) {
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = propsNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
|
||||
String type;
|
||||
JsonNode typeNode = propNode.get("type");
|
||||
if (typeNode != null) {
|
||||
type = typeNode.getTextValue();
|
||||
} else {
|
||||
// lets see if we can derive this...
|
||||
if (propNode.isObject() && propNode.get("properties") != null) {
|
||||
type = JsonObjectMapper.JSON_TYPE;
|
||||
} else if (propNode.isObject() && propNode.get("fields") != null) {
|
||||
type = JsonMultiFieldMapper.JSON_TYPE;
|
||||
} else {
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
}
|
||||
if (type.equals(JsonStringFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseString(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonDateFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseDate(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonShortFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseShort(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonIntegerFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseInteger(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonLongFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseLong(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonFloatFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseFloat(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonDoubleFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseDouble(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonBooleanFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseBoolean(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonObjectMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseObject(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonMultiFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseMultiField(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonBinaryFieldMapper.JSON_TYPE)) {
|
||||
objBuilder.add(parseBinary(propName, (ObjectNode) propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonMultiFieldMapper.Builder parseMultiField(String name, ObjectNode multiFieldNode) {
|
||||
JsonMultiFieldMapper.Builder builder = multiField(name);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = multiFieldNode.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
String fieldName = entry.getKey();
|
||||
JsonNode fieldNode = entry.getValue();
|
||||
if (fieldName.equals("pathType")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
|
||||
} else if (fieldName.equals("fields")) {
|
||||
ObjectNode fieldsNode = (ObjectNode) fieldNode;
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldsNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry1 = propsIt.next();
|
||||
String propName = entry1.getKey();
|
||||
JsonNode propNode = entry1.getValue();
|
||||
|
||||
String type;
|
||||
JsonNode typeNode = propNode.get("type");
|
||||
if (typeNode != null) {
|
||||
type = typeNode.getTextValue();
|
||||
} else {
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
|
||||
if (type.equals(JsonStringFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseString(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonDateFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseDate(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonIntegerFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseInteger(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonLongFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseLong(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonFloatFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseFloat(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonDoubleFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseDouble(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonBooleanFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseBoolean(propName, (ObjectNode) propNode));
|
||||
} else if (type.equals(JsonBinaryFieldMapper.JSON_TYPE)) {
|
||||
builder.add(parseBinary(propName, (ObjectNode) propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonDateFieldMapper.Builder parseDate(String name, ObjectNode dateNode) {
|
||||
JsonDateFieldMapper.Builder builder = dateField(name);
|
||||
parseNumberField(builder, name, dateNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = dateNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(propNode.getValueAsText());
|
||||
} else if (propName.equals("format")) {
|
||||
builder.dateTimeFormatter(parseDateTimeFormatter(propName, propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonShortFieldMapper.Builder parseShort(String name, ObjectNode integerNode) {
|
||||
JsonShortFieldMapper.Builder builder = shortField(name);
|
||||
parseNumberField(builder, name, integerNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = integerNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeShortValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private JsonIntegerFieldMapper.Builder parseInteger(String name, ObjectNode integerNode) {
|
||||
JsonIntegerFieldMapper.Builder builder = integerField(name);
|
||||
parseNumberField(builder, name, integerNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = integerNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeIntegerValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonLongFieldMapper.Builder parseLong(String name, ObjectNode longNode) {
|
||||
JsonLongFieldMapper.Builder builder = longField(name);
|
||||
parseNumberField(builder, name, longNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = longNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeLongValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonFloatFieldMapper.Builder parseFloat(String name, ObjectNode floatNode) {
|
||||
JsonFloatFieldMapper.Builder builder = floatField(name);
|
||||
parseNumberField(builder, name, floatNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = floatNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeFloatValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonDoubleFieldMapper.Builder parseDouble(String name, ObjectNode doubleNode) {
|
||||
JsonDoubleFieldMapper.Builder builder = doubleField(name);
|
||||
parseNumberField(builder, name, doubleNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = doubleNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeDoubleValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonStringFieldMapper.Builder parseString(String name, ObjectNode stringNode) {
|
||||
JsonStringFieldMapper.Builder builder = stringField(name);
|
||||
parseJsonField(builder, name, stringNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = stringNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(propNode.getValueAsText());
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonBinaryFieldMapper.Builder parseBinary(String name, ObjectNode binaryNode) {
|
||||
JsonBinaryFieldMapper.Builder builder = binaryField(name);
|
||||
parseJsonField(builder, name, binaryNode);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonBooleanFieldMapper.Builder parseBoolean(String name, ObjectNode booleanNode) {
|
||||
JsonBooleanFieldMapper.Builder builder = booleanField(name);
|
||||
parseJsonField(builder, name, booleanNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = booleanNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeBooleanValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void parseNumberField(JsonNumberFieldMapper.Builder builder, String name, ObjectNode numberNode) {
|
||||
parseJsonField(builder, name, numberNode);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = numberNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("precisionStep")) {
|
||||
builder.precisionStep(nodeIntegerValue(propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseJsonField(JsonFieldMapper.Builder builder, String name, ObjectNode fieldNode) {
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("indexName")) {
|
||||
builder.indexName(propNode.getTextValue());
|
||||
} else if (propName.equals("store")) {
|
||||
builder.store(parseStore(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("index")) {
|
||||
builder.index(parseIndex(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("termVector")) {
|
||||
builder.termVector(parseTermVector(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("boost")) {
|
||||
builder.boost(nodeFloatValue(propNode));
|
||||
} else if (propName.equals("omitNorms")) {
|
||||
builder.omitNorms(nodeBooleanValue(propNode));
|
||||
} else if (propName.equals("omitTermFreqAndPositions")) {
|
||||
builder.omitTermFreqAndPositions(nodeBooleanValue(propNode));
|
||||
} else if (propName.equals("indexAnalyzer")) {
|
||||
builder.indexAnalyzer(analysisService.analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("searchAnalyzer")) {
|
||||
builder.searchAnalyzer(analysisService.analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("analyzer")) {
|
||||
builder.indexAnalyzer(analysisService.analyzer(propNode.getTextValue()));
|
||||
builder.searchAnalyzer(analysisService.analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("includeInAll")) {
|
||||
builder.includeInAll(nodeBooleanValue(propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FormatDateTimeFormatter parseDateTimeFormatter(String fieldName, JsonNode node) {
|
||||
if (node.isTextual()) {
|
||||
return Joda.forPattern(node.getTextValue());
|
||||
} else {
|
||||
// TODO support more complex configuration...
|
||||
throw new MapperParsingException("Wrong node to use to parse date formatters [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private Field.TermVector parseTermVector(String fieldName, String termVector) throws MapperParsingException {
|
||||
if ("no".equals(termVector)) {
|
||||
return Field.TermVector.NO;
|
||||
} else if ("yes".equals(termVector)) {
|
||||
return Field.TermVector.YES;
|
||||
} else if ("with_offsets".equals(termVector)) {
|
||||
return Field.TermVector.WITH_OFFSETS;
|
||||
} else if ("with_positions".equals(termVector)) {
|
||||
return Field.TermVector.WITH_POSITIONS;
|
||||
} else if ("with_positions_offsets".equals(termVector)) {
|
||||
return Field.TermVector.WITH_POSITIONS_OFFSETS;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for termVector [" + termVector + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private Field.Index parseIndex(String fieldName, String index) throws MapperParsingException {
|
||||
if ("no".equals(index)) {
|
||||
return Field.Index.NO;
|
||||
} else if ("not_analyzed".equals(index)) {
|
||||
return Field.Index.NOT_ANALYZED;
|
||||
} else if ("analyzed".equals(index)) {
|
||||
return Field.Index.ANALYZED;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for index [" + index + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private Field.Store parseStore(String fieldName, String store) throws MapperParsingException {
|
||||
if ("no".equals(store)) {
|
||||
return Field.Store.NO;
|
||||
} else if ("yes".equals(store)) {
|
||||
return Field.Store.YES;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for store [" + store + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface JsonTypeParser {
|
||||
|
||||
public static class ParserContext {
|
||||
|
||||
private final AnalysisService analysisService;
|
||||
|
||||
private final ObjectNode rootNode;
|
||||
|
||||
private final ImmutableMap<String, JsonTypeParser> typeParsers;
|
||||
|
||||
public ParserContext(ObjectNode rootNode, AnalysisService analysisService, ImmutableMap<String, JsonTypeParser> typeParsers) {
|
||||
this.analysisService = analysisService;
|
||||
this.rootNode = rootNode;
|
||||
this.typeParsers = typeParsers;
|
||||
}
|
||||
|
||||
public AnalysisService analysisService() {
|
||||
return analysisService;
|
||||
}
|
||||
|
||||
public ObjectNode rootNode() {
|
||||
return this.rootNode;
|
||||
}
|
||||
|
||||
public JsonTypeParser typeParser(String type) {
|
||||
return typeParsers.get(type);
|
||||
}
|
||||
}
|
||||
|
||||
JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException;
|
||||
}
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.node.ArrayNode;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
|
||||
import org.elasticsearch.util.joda.Joda;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.collect.Lists.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonTypeParsers {
|
||||
|
||||
public static class JsonObjectTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode objectNode = (ObjectNode) node;
|
||||
JsonObjectMapper.Builder builder = object(name);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = objectNode.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
String fieldName = entry.getKey();
|
||||
JsonNode fieldNode = entry.getValue();
|
||||
if (fieldName.equals("dynamic")) {
|
||||
builder.dynamic(nodeBooleanValue(fieldNode));
|
||||
} else if (fieldName.equals("type")) {
|
||||
String type = fieldNode.getTextValue();
|
||||
if (!type.equals("object")) {
|
||||
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
|
||||
}
|
||||
} else if (fieldName.equals("dateFormats")) {
|
||||
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
||||
if (fieldNode.isArray()) {
|
||||
for (JsonNode node1 : (ArrayNode) fieldNode) {
|
||||
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
|
||||
}
|
||||
} else if ("none".equals(fieldNode.getValueAsText())) {
|
||||
dateTimeFormatters = null;
|
||||
} else {
|
||||
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
|
||||
}
|
||||
if (dateTimeFormatters == null) {
|
||||
builder.noDateTimeFormatter();
|
||||
} else {
|
||||
builder.dateTimeFormatter(dateTimeFormatters);
|
||||
}
|
||||
} else if (fieldName.equals("enabled")) {
|
||||
builder.enabled(nodeBooleanValue(fieldNode));
|
||||
} else if (fieldName.equals("pathType")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
|
||||
} else if (fieldName.equals("properties")) {
|
||||
parseProperties(builder, (ObjectNode) fieldNode, parserContext);
|
||||
} else if (fieldName.equals("includeInAll")) {
|
||||
builder.includeInAll(nodeBooleanValue(fieldNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void parseProperties(JsonObjectMapper.Builder objBuilder, ObjectNode propsNode, JsonTypeParser.ParserContext parserContext) {
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = propsNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
|
||||
String type;
|
||||
JsonNode typeNode = propNode.get("type");
|
||||
if (typeNode != null) {
|
||||
type = typeNode.getTextValue();
|
||||
} else {
|
||||
// lets see if we can derive this...
|
||||
if (propNode.isObject() && propNode.get("properties") != null) {
|
||||
type = JsonObjectMapper.JSON_TYPE;
|
||||
} else if (propNode.isObject() && propNode.get("fields") != null) {
|
||||
type = JsonMultiFieldMapper.JSON_TYPE;
|
||||
} else {
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
JsonTypeParser typeParser = parserContext.typeParser(type);
|
||||
if (typeParser == null) {
|
||||
throw new MapperParsingException("No handler for type [" + type + "] declared on field [" + propName + "]");
|
||||
}
|
||||
objBuilder.add(typeParser.parse(propName, propNode, parserContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonMultiFieldTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode multiFieldNode = (ObjectNode) node;
|
||||
JsonMultiFieldMapper.Builder builder = multiField(name);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = multiFieldNode.getFields(); fieldsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = fieldsIt.next();
|
||||
String fieldName = entry.getKey();
|
||||
JsonNode fieldNode = entry.getValue();
|
||||
if (fieldName.equals("pathType")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
|
||||
} else if (fieldName.equals("fields")) {
|
||||
ObjectNode fieldsNode = (ObjectNode) fieldNode;
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldsNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry1 = propsIt.next();
|
||||
String propName = entry1.getKey();
|
||||
JsonNode propNode = entry1.getValue();
|
||||
|
||||
String type;
|
||||
JsonNode typeNode = propNode.get("type");
|
||||
if (typeNode != null) {
|
||||
type = typeNode.getTextValue();
|
||||
} else {
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
|
||||
JsonTypeParser typeParser = parserContext.typeParser(type);
|
||||
if (typeParser == null) {
|
||||
throw new MapperParsingException("No handler for type [" + type + "] declared on field [" + fieldName + "]");
|
||||
}
|
||||
builder.add(typeParser.parse(propName, propNode, parserContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonDateTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode dateNode = (ObjectNode) node;
|
||||
JsonDateFieldMapper.Builder builder = dateField(name);
|
||||
parseNumberField(builder, name, dateNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = dateNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(propNode.getValueAsText());
|
||||
} else if (propName.equals("format")) {
|
||||
builder.dateTimeFormatter(parseDateTimeFormatter(propName, propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonShortTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode shortNode = (ObjectNode) node;
|
||||
JsonShortFieldMapper.Builder builder = shortField(name);
|
||||
parseNumberField(builder, name, shortNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = shortNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeShortValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonIntegerTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode integerNode = (ObjectNode) node;
|
||||
JsonIntegerFieldMapper.Builder builder = integerField(name);
|
||||
parseNumberField(builder, name, integerNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = integerNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeIntegerValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonLongTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode longNode = (ObjectNode) node;
|
||||
JsonLongFieldMapper.Builder builder = longField(name);
|
||||
parseNumberField(builder, name, longNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = longNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeLongValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonFloatTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode floatNode = (ObjectNode) node;
|
||||
JsonFloatFieldMapper.Builder builder = floatField(name);
|
||||
parseNumberField(builder, name, floatNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = floatNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeFloatValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonDoubleTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode doubleNode = (ObjectNode) node;
|
||||
JsonDoubleFieldMapper.Builder builder = doubleField(name);
|
||||
parseNumberField(builder, name, doubleNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = doubleNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeDoubleValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonStringTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode stringNode = (ObjectNode) node;
|
||||
JsonStringFieldMapper.Builder builder = stringField(name);
|
||||
parseJsonField(builder, name, stringNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = stringNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(propNode.getValueAsText());
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonBinaryTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode binaryNode = (ObjectNode) node;
|
||||
JsonBinaryFieldMapper.Builder builder = binaryField(name);
|
||||
parseJsonField(builder, name, binaryNode, parserContext);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonBooleanTypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
|
||||
ObjectNode booleanNode = (ObjectNode) node;
|
||||
JsonBooleanFieldMapper.Builder builder = booleanField(name);
|
||||
parseJsonField(builder, name, booleanNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = booleanNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("nullValue")) {
|
||||
builder.nullValue(nodeBooleanValue(propNode));
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseNumberField(JsonNumberFieldMapper.Builder builder, String name, ObjectNode numberNode, JsonTypeParser.ParserContext parserContext) {
|
||||
parseJsonField(builder, name, numberNode, parserContext);
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = numberNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("precisionStep")) {
|
||||
builder.precisionStep(nodeIntegerValue(propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseJsonField(JsonFieldMapper.Builder builder, String name, ObjectNode fieldNode, JsonTypeParser.ParserContext parserContext) {
|
||||
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldNode.getFields(); propsIt.hasNext();) {
|
||||
Map.Entry<String, JsonNode> entry = propsIt.next();
|
||||
String propName = entry.getKey();
|
||||
JsonNode propNode = entry.getValue();
|
||||
if (propName.equals("indexName")) {
|
||||
builder.indexName(propNode.getTextValue());
|
||||
} else if (propName.equals("store")) {
|
||||
builder.store(parseStore(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("index")) {
|
||||
builder.index(parseIndex(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("termVector")) {
|
||||
builder.termVector(parseTermVector(name, propNode.getTextValue()));
|
||||
} else if (propName.equals("boost")) {
|
||||
builder.boost(nodeFloatValue(propNode));
|
||||
} else if (propName.equals("omitNorms")) {
|
||||
builder.omitNorms(nodeBooleanValue(propNode));
|
||||
} else if (propName.equals("omitTermFreqAndPositions")) {
|
||||
builder.omitTermFreqAndPositions(nodeBooleanValue(propNode));
|
||||
} else if (propName.equals("indexAnalyzer")) {
|
||||
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("searchAnalyzer")) {
|
||||
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("analyzer")) {
|
||||
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
|
||||
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
|
||||
} else if (propName.equals("includeInAll")) {
|
||||
builder.includeInAll(nodeBooleanValue(propNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FormatDateTimeFormatter parseDateTimeFormatter(String fieldName, JsonNode node) {
|
||||
if (node.isTextual()) {
|
||||
return Joda.forPattern(node.getTextValue());
|
||||
} else {
|
||||
// TODO support more complex configuration...
|
||||
throw new MapperParsingException("Wrong node to use to parse date formatters [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static Field.TermVector parseTermVector(String fieldName, String termVector) throws MapperParsingException {
|
||||
if ("no".equals(termVector)) {
|
||||
return Field.TermVector.NO;
|
||||
} else if ("yes".equals(termVector)) {
|
||||
return Field.TermVector.YES;
|
||||
} else if ("with_offsets".equals(termVector)) {
|
||||
return Field.TermVector.WITH_OFFSETS;
|
||||
} else if ("with_positions".equals(termVector)) {
|
||||
return Field.TermVector.WITH_POSITIONS;
|
||||
} else if ("with_positions_offsets".equals(termVector)) {
|
||||
return Field.TermVector.WITH_POSITIONS_OFFSETS;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for termVector [" + termVector + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static Field.Index parseIndex(String fieldName, String index) throws MapperParsingException {
|
||||
if ("no".equals(index)) {
|
||||
return Field.Index.NO;
|
||||
} else if ("not_analyzed".equals(index)) {
|
||||
return Field.Index.NOT_ANALYZED;
|
||||
} else if ("analyzed".equals(index)) {
|
||||
return Field.Index.ANALYZED;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for index [" + index + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static Field.Store parseStore(String fieldName, String store) throws MapperParsingException {
|
||||
if ("no".equals(store)) {
|
||||
return Field.Store.NO;
|
||||
} else if ("yes".equals(store)) {
|
||||
return Field.Store.YES;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for store [" + store + "] for field [" + fieldName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonPath.Type parsePathType(String name, String path) throws MapperParsingException {
|
||||
if ("justName".equals(path) || "just_name".equals(path)) {
|
||||
return JsonPath.Type.JUST_NAME;
|
||||
} else if ("full".equals(path)) {
|
||||
return JsonPath.Type.FULL;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for pathType [" + path + "] for objet [" + name + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -12,9 +12,9 @@
|
|||
"object1" : {
|
||||
properties : {
|
||||
"multi1" : {
|
||||
type : "multi-field",
|
||||
type : "multi_field",
|
||||
"fields" : {
|
||||
"number" : {type: "int"},
|
||||
"number" : {type: "integer"},
|
||||
"string" : {type: "string", index : "not_analyzed"}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue