/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. 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. */ using System; using System.Collections.Generic; using System.Runtime.Serialization; using OpenSearch.Net.Utf8Json; namespace OpenSearch.Client { [InterfaceDataContract] [ReadAs(typeof(TypeMapping))] public interface ITypeMapping { /// /// If enabled (default), then new string fields are checked to see whether their contents match /// any of the date patterns specified in . /// If a match is found, a new date field is added with the corresponding format. /// [DataMember(Name = "date_detection")] bool? DateDetection { get; set; } /// /// Whether new unseen fields will be added to the mapping. Default is true. /// A value of false will ignore unknown fields and a value of /// will result in an error if an unknown field is encountered in a document. /// [DataMember(Name = "dynamic")] [JsonFormatter(typeof(DynamicMappingFormatter))] Union Dynamic { get; set; } /// /// Date formats used by /// [DataMember(Name = "dynamic_date_formats")] IEnumerable DynamicDateFormats { get; set; } /// /// Dynamic templates allow you to define custom mappings that can be applied to dynamically added fields based on /// - the datatype detected by OpenSearch, with . /// - the name of the field, with and or /// . /// - the full dotted path to the field, with and /// . /// The original field name {name} and the detected datatype {dynamic_type} template variables can be /// used in the mapping specification as placeholders. /// [DataMember(Name = "dynamic_templates")] IDynamicTemplateContainer DynamicTemplates { get; set; } /// /// Used to index the names of every field in a document that contains any value other than null. /// This field was used by the exists query to find documents that either have or don’t have any non-null value for a particular field. /// Now, it only indexes the names of fields that have doc_values and norms disabled. /// Can be disabled. Disabling _field_names is often not necessary because it no longer carries the index overhead it once did. /// If you have a lot of fields which have doc_values and norms disabled and you do not need to execute exists queries /// using those fields you might want to disable /// [DataMember(Name = "_field_names")] IFieldNamesField FieldNamesField { get; set; } /// /// Custom meta data to associate with a mapping. Not used by OpenSearch, /// but can be used to store application-specific metadata. /// [DataMember(Name = "_meta")] [JsonFormatter(typeof(VerbatimDictionaryInterfaceKeysFormatter))] IDictionary Meta { get; set; } /// /// If enabled (not enabled by default), then new string fields are checked to see whether /// they wholly contain a numeric value and if so, to map as a numeric field. /// [DataMember(Name = "numeric_detection")] bool? NumericDetection { get; set; } /// /// Specifies the mapping properties /// [DataMember(Name = "properties")] IProperties Properties { get; set; } /// /// Specifies configuration for the _routing parameter /// [DataMember(Name = "_routing")] IRoutingField RoutingField { get; set; } /// /// Specifies runtime fields for the mapping. /// [DataMember(Name = "runtime")] IRuntimeFields RuntimeFields { get; set; } /// /// If enabled, indexes the size in bytes of the original _source field. /// Requires mapper-size plugin be installed /// [DataMember(Name = "_size")] ISizeField SizeField { get; set; } /// /// Specifies configuration for the _source field /// [DataMember(Name = "_source")] ISourceField SourceField { get; set; } } public class TypeMapping : ITypeMapping { /// public bool? DateDetection { get; set; } /// public Union Dynamic { get; set; } /// public IEnumerable DynamicDateFormats { get; set; } /// public IDynamicTemplateContainer DynamicTemplates { get; set; } /// public IFieldNamesField FieldNamesField { get; set; } /// public IDictionary Meta { get; set; } /// public bool? NumericDetection { get; set; } /// public IProperties Properties { get; set; } /// public IRoutingField RoutingField { get; set; } /// public IRuntimeFields RuntimeFields { get; set; } /// public ISizeField SizeField { get; set; } /// public ISourceField SourceField { get; set; } } public class TypeMappingDescriptor : DescriptorBase, ITypeMapping>, ITypeMapping where T : class { bool? ITypeMapping.DateDetection { get; set; } Union ITypeMapping.Dynamic { get; set; } IEnumerable ITypeMapping.DynamicDateFormats { get; set; } IDynamicTemplateContainer ITypeMapping.DynamicTemplates { get; set; } IFieldNamesField ITypeMapping.FieldNamesField { get; set; } IDictionary ITypeMapping.Meta { get; set; } bool? ITypeMapping.NumericDetection { get; set; } IProperties ITypeMapping.Properties { get; set; } IRoutingField ITypeMapping.RoutingField { get; set; } IRuntimeFields ITypeMapping.RuntimeFields { get; set; } ISizeField ITypeMapping.SizeField { get; set; } ISourceField ITypeMapping.SourceField { get; set; } /// /// Convenience method to map as much as it can based on attributes set on the /// type, as well as inferring mappings from the CLR property types. ///
This method also automatically sets up mappings for known values types (int, long, double, datetime, etc)
///
Class types default to object and Enums to int
///
Later calls can override whatever is set is by this call.
///
public TypeMappingDescriptor AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) => Assign(Self.Properties.AutoMap(visitor, maxRecursion), (a, v) => a.Properties = v); /// /// Convenience method to map as much as it can based on attributes set on the /// type, as well as inferring mappings from the CLR property types. /// This particular overload is useful for automapping any children ///
This method also automatically sets up mappings for known values types (int, long, double, datetime, etc)
///
Class types default to object and Enums to int
///
Later calls can override whatever is set is by this call.
///
public TypeMappingDescriptor AutoMap(Type documentType, IPropertyVisitor visitor = null, int maxRecursion = 0) { if (!documentType.IsClass) throw new ArgumentException("must be a reference type", nameof(documentType)); return Assign(Self.Properties.AutoMap(documentType, visitor, maxRecursion), (a, v) => a.Properties = v); } /// /// Convenience method to map as much as it can based on attributes set on the /// type, as well as inferring mappings from the CLR property types. /// This particular overload is useful for automapping any children ///
This method also automatically sets up mappings for known values types (int, long, double, datetime, etc)
///
Class types default to object and Enums to int
///
Later calls can override whatever is set is by this call.
///
public TypeMappingDescriptor AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) where TDocument : class => Assign(Self.Properties.AutoMap(visitor, maxRecursion), (a, v) => a.Properties = v); /// /// Convenience method to map as much as it can based on attributes set on the /// type, as well as inferring mappings from the CLR property types. /// This overload determines how deep automapping should recurse on a complex CLR type. /// public TypeMappingDescriptor AutoMap(int maxRecursion) => AutoMap(null, maxRecursion); /// public TypeMappingDescriptor Dynamic(Union dynamic) => Assign(dynamic, (a, v) => a.Dynamic = v); /// public TypeMappingDescriptor Dynamic(bool dynamic = true) => Assign(dynamic, (a, v) => a.Dynamic = v); /// public TypeMappingDescriptor SizeField(Func sizeFieldSelector) => Assign(sizeFieldSelector, (a, v) => a.SizeField = v?.Invoke(new SizeFieldDescriptor())); /// public TypeMappingDescriptor SourceField(Func sourceFieldSelector) => Assign(sourceFieldSelector, (a, v) => a.SourceField = v?.Invoke(new SourceFieldDescriptor())); /// public TypeMappingDescriptor DisableSizeField(bool? disabled = true) => Assign(new SizeField { Enabled = !disabled }, (a, v) => a.SizeField = v); /// public TypeMappingDescriptor DynamicDateFormats(IEnumerable dateFormats) => Assign(dateFormats, (a, v) => a.DynamicDateFormats = v); /// public TypeMappingDescriptor DateDetection(bool? detect = true) => Assign(detect, (a, v) => a.DateDetection = v); /// public TypeMappingDescriptor NumericDetection(bool? detect = true) => Assign(detect, (a, v) => a.NumericDetection = v); /// public TypeMappingDescriptor RoutingField(Func, IRoutingField> routingFieldSelector) => Assign(routingFieldSelector, (a, v) => a.RoutingField = v?.Invoke(new RoutingFieldDescriptor())); public TypeMappingDescriptor RuntimeFields(Func, IPromise> runtimeFieldsSelector) => Assign(runtimeFieldsSelector, (a, v) => a.RuntimeFields = v?.Invoke(new RuntimeFieldsDescriptor())?.Value); /// public TypeMappingDescriptor RuntimeFields(Func, IPromise> runtimeFieldsSelector) where TDocument : class => Assign(runtimeFieldsSelector, (a, v) => a.RuntimeFields = v?.Invoke(new RuntimeFieldsDescriptor())?.Value); /// public TypeMappingDescriptor FieldNamesField(Func, IFieldNamesField> fieldNamesFieldSelector) => Assign(fieldNamesFieldSelector.Invoke(new FieldNamesFieldDescriptor()), (a, v) => a.FieldNamesField = v); /// public TypeMappingDescriptor Meta(Func, FluentDictionary> metaSelector) => Assign(metaSelector(new FluentDictionary()), (a, v) => a.Meta = v); /// public TypeMappingDescriptor Meta(Dictionary metaDictionary) => Assign(metaDictionary, (a, v) => a.Meta = v); /// public TypeMappingDescriptor Properties(Func, IPromise> propertiesSelector) => Assign(propertiesSelector, (a, v) => a.Properties = v?.Invoke(new PropertiesDescriptor(Self.Properties))?.Value); /// public TypeMappingDescriptor Properties(Func, IPromise> propertiesSelector) where TDocument : class => Assign(propertiesSelector, (a, v) => a.Properties = v?.Invoke(new PropertiesDescriptor(Self.Properties))?.Value); /// public TypeMappingDescriptor DynamicTemplates( Func, IPromise> dynamicTemplatesSelector ) => Assign(dynamicTemplatesSelector, (a, v) => a.DynamicTemplates = v?.Invoke(new DynamicTemplateContainerDescriptor())?.Value); } }