/** * Given a type (eg. long, string, ...), return an anonymous field mapper that can be used for * search operations. */ public MappedFieldType unmappedFieldType(String type) { if (type.equals("string")) { deprecationLogger.deprecated( "[unmapped_type:string] should be replaced with [unmapped_type:keyword]"); type = "keyword"; } MappedFieldType fieldType = unmappedFieldTypes.get(type); if (fieldType == null) { final Mapper.TypeParser.ParserContext parserContext = documentMapperParser().parserContext(type); Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new IllegalArgumentException("No mapper found for type [" + type + "]"); } final Mapper.Builder<?, ?> builder = typeParser.parse("__anonymous_" + type, emptyMap(), parserContext); final BuilderContext builderContext = new BuilderContext(indexSettings.getSettings(), new ContentPath(1)); fieldType = ((FieldMapper) builder.build(builderContext)).fieldType(); // There is no need to synchronize writes here. In the case of concurrent access, we could // just // compute some mappers several times, which is not a big deal Map<String, MappedFieldType> newUnmappedFieldTypes = new HashMap<>(); newUnmappedFieldTypes.putAll(unmappedFieldTypes); newUnmappedFieldTypes.put(type, fieldType); unmappedFieldTypes = unmodifiableMap(newUnmappedFieldTypes); } return fieldType; }
private void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.get("fields") != null) { type = MultiFieldMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser 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)); } }
/** * Given a type (eg. long, string, ...), return an anonymous field mapper that can be used for * search operations. */ public MappedFieldType unmappedFieldType(String type) { final ImmutableMap<String, MappedFieldType> unmappedFieldMappers = this.unmappedFieldTypes; MappedFieldType fieldType = unmappedFieldMappers.get(type); if (fieldType == null) { final Mapper.TypeParser.ParserContext parserContext = documentMapperParser().parserContext(); Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new IllegalArgumentException("No mapper found for type [" + type + "]"); } final Mapper.Builder<?, ?> builder = typeParser.parse("__anonymous_" + type, ImmutableMap.<String, Object>of(), parserContext); final BuilderContext builderContext = new BuilderContext(indexSettings, new ContentPath(1)); fieldType = ((FieldMapper) builder.build(builderContext)).fieldType(); // There is no need to synchronize writes here. In the case of concurrent access, we could // just // compute some mappers several times, which is not a big deal this.unmappedFieldTypes = ImmutableMap.<String, MappedFieldType>builder() .putAll(unmappedFieldMappers) .put(type, fieldType) .build(); } return fieldType; }
public Mapper.Builder findTemplateBuilder( ParseContext context, String name, String dynamicType, String matchType) { DynamicTemplate dynamicTemplate = findTemplate(context.path(), name, matchType); if (dynamicTemplate == null) { return null; } Mapper.TypeParser.ParserContext parserContext = context.docMapperParser().parserContext(); String mappingType = dynamicTemplate.mappingType(dynamicType); Mapper.TypeParser typeParser = parserContext.typeParser(mappingType); if (typeParser == null) { throw new MapperParsingException( "failed to find type parsed [" + mappingType + "] for [" + name + "]"); } return typeParser.parse(name, dynamicTemplate.mappingForName(name, dynamicType), parserContext); }
private Mapper.Builder<?, ?> findMapperBuilder( Map<String, Object> propNode, String propName, ParserContext parserContext) { String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { type = "string"; } Mapper.TypeParser typeParser = parserContext.typeParser(type); Mapper.Builder<?, ?> mapperBuilder = typeParser.parse(propName, (Map<String, Object>) propNode, parserContext); return mapperBuilder; }
protected static void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); // Should accept empty arrays, as a work around for when the user can't provide an empty // Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List<?>) entry.getValue()).isEmpty(); if (entry.getValue() instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled flag on it, make it an object // (usually, setting enabled to false to not index any type, including core values, // which // non enabled object type supports). type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser 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)); } else if (!isEmptyList) { throw new MapperParsingException( "Expected map for property [fields] on field [" + propName + "] but got a " + propName.getClass()); } } }
private void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.get("fields") != null) { type = MultiFieldMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled flag on it, make it an object // (usually, setting enabled to false to not index any type, including core values, // which // non enabled object type supports). type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser 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)); } }
protected static void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { Iterator<Map.Entry<String, Object>> iterator = propsNode.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> entry = iterator.next(); String propName = entry.getKey(); // Should accept empty arrays, as a work around for when the // user can't provide an empty Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List<?>) entry.getValue()).isEmpty(); if (entry.getValue() instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled // flag on it, make it an object // (usually, setting enabled to false to not index // any type, including core values, which type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser 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)); propNode.remove("type"); DocumentMapperParser.checkNoRemainingFields( propName, propNode, parserContext.indexVersionCreated()); iterator.remove(); } else if (isEmptyList) { iterator.remove(); } else { throw new MapperParsingException( "Expected map for property [fields] on field [" + propName + "] but got a " + propName.getClass()); } } DocumentMapperParser.checkNoRemainingFields( propsNode, parserContext.indexVersionCreated(), "DocType mapping definition has unsupported parameters: "); }
@Override public Mapper.Builder<?, ?> parse( String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException { ContentPath.Type pathType = null; FieldMapper.Builder mainFieldBuilder = null; List<FieldMapper.Builder> fields = null; String firstType = null; for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext(); ) { Map.Entry<String, Object> entry = iterator.next(); String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) { pathType = parsePathType(name, fieldNode.toString()); iterator.remove(); } else if (fieldName.equals("fields")) { Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode; for (Iterator<Map.Entry<String, Object>> fieldsIterator = fieldsNode.entrySet().iterator(); fieldsIterator.hasNext(); ) { Map.Entry<String, Object> entry1 = fieldsIterator.next(); String propName = entry1.getKey(); Map<String, Object> propNode = (Map<String, Object>) entry1.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); if (firstType == null) { firstType = type; } } else { throw new MapperParsingException( "no type specified for property [" + propName + "]"); } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "no handler for type [" + type + "] declared on field [" + fieldName + "]"); } if (propName.equals(name)) { mainFieldBuilder = (FieldMapper.Builder) typeParser.parse(propName, propNode, parserContext); fieldsIterator.remove(); } else { if (fields == null) { fields = new ArrayList<>(2); } fields.add( (FieldMapper.Builder) typeParser.parse(propName, propNode, parserContext)); fieldsIterator.remove(); } } fieldsNode.remove("type"); DocumentMapperParser.checkNoRemainingFields( fieldName, fieldsNode, parserContext.indexVersionCreated()); iterator.remove(); } } if (mainFieldBuilder == null) { if (fields == null) { // No fields at all were specified in multi_field, so lets return a non indexed string // field. return new StringFieldMapper.Builder(name).index(false); } Mapper.TypeParser typeParser = parserContext.typeParser(firstType); if (typeParser == null) { // The first multi field's type is unknown mainFieldBuilder = new StringFieldMapper.Builder(name).index(false); } else { Mapper.Builder substitute = typeParser.parse(name, Collections.<String, Object>emptyMap(), parserContext); if (substitute instanceof FieldMapper.Builder) { mainFieldBuilder = ((FieldMapper.Builder) substitute).index(false); } else { // The first multi isn't a core field type mainFieldBuilder = new StringFieldMapper.Builder(name).index(false); } } } if (fields != null && pathType != null) { for (Mapper.Builder field : fields) { mainFieldBuilder.addMultiField(field); } mainFieldBuilder.multiFieldPathType(pathType); } else if (fields != null) { for (Mapper.Builder field : fields) { mainFieldBuilder.addMultiField(field); } } else if (pathType != null) { mainFieldBuilder.multiFieldPathType(pathType); } return mainFieldBuilder; }
public static boolean parseMultiField( FieldMapper.Builder builder, String name, Mapper.TypeParser.ParserContext parserContext, String propName, Object propNode) { parserContext = parserContext.createMultiFieldContext(parserContext); if (propName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0_beta1)) { builder.multiFieldPathType(parsePathType(name, propNode.toString())); return true; } else if (propName.equals("fields")) { final Map<String, Object> multiFieldsPropNodes; if (propNode instanceof List && ((List<?>) propNode).isEmpty()) { multiFieldsPropNodes = Collections.emptyMap(); } else if (propNode instanceof Map) { multiFieldsPropNodes = (Map<String, Object>) propNode; } else { throw new MapperParsingException( "expected map for property [fields] on field [" + propNode + "] or " + "[" + propName + "] but got a " + propNode.getClass()); } for (Map.Entry<String, Object> multiFieldEntry : multiFieldsPropNodes.entrySet()) { String multiFieldName = multiFieldEntry.getKey(); if (multiFieldName.contains(".")) { throw new MapperParsingException( "Field name [" + multiFieldName + "] which is a multi field of [" + name + "] cannot contain '.'"); } if (!(multiFieldEntry.getValue() instanceof Map)) { throw new MapperParsingException( "illegal field [" + multiFieldName + "], only fields can be specified inside fields"); } @SuppressWarnings("unchecked") Map<String, Object> multiFieldNodes = (Map<String, Object>) multiFieldEntry.getValue(); String type; Object typeNode = multiFieldNodes.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { throw new MapperParsingException( "no type specified for property [" + multiFieldName + "]"); } if (type.equals(ObjectMapper.CONTENT_TYPE) || type.equals(ObjectMapper.NESTED_CONTENT_TYPE)) { throw new MapperParsingException("Type [" + type + "] cannot be used in multi field"); } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "no handler for type [" + type + "] declared on field [" + multiFieldName + "]"); } builder.addMultiField(typeParser.parse(multiFieldName, multiFieldNodes, parserContext)); multiFieldNodes.remove("type"); DocumentMapperParser.checkNoRemainingFields( propName, multiFieldNodes, parserContext.indexVersionCreated()); } return true; } return false; }