diff --git a/docs/contents/nest/indices/put-mapping.markdown b/docs/contents/nest/indices/put-mapping.markdown index 417b7c354e3..6020b82ffdf 100644 --- a/docs/contents/nest/indices/put-mapping.markdown +++ b/docs/contents/nest/indices/put-mapping.markdown @@ -61,41 +61,37 @@ You can persist this mapping by simpling calling You can also create mappings on the fly: - var typeMapping = new TypeMapping(Guid.NewGuid().ToString("n")); - var property = new TypeMappingProperty + var indexDefinition = new RootObjectMapping { - Type = "multi_field" + Properties = new Dictionary(), + Name = indexName }; - var primaryField = new TypeMappingProperty + var property = new StringMapping { - Type = "string", Index = "not_analyzed" }; - var analyzedField = new TypeMappingProperty + var analyzedField = new StringMapping { - Type = "string", Index = "analyzed" }; - property.Fields = new Dictionary(); - property.Fields.Add("name", primaryField); property.Fields.Add("name_analyzed", analyzedField); + indexDefinition.Properties.Add("name", property); + this.ConnectedClient.Map(x => x.InitializeUsing(indexDefinition)); - typeMapping.Properties.Add("name", property); - this.ConnectedClient.Map(typeMapping); ## Multifield Mapping To create multifield type you can use following example. var result = this._client.Map(m => m .Properties(props => props - .MultiField(s => s + .String(s => s .Name(p => p.Name) .Path(MultiFieldMappingPath.Full) + .Index(FieldIndexOption.not_analyzed) .Fields(pprops => pprops - .String(ps => ps.Name(p => p.Name).Index(FieldIndexOption.not_analyzed)) .String(ps => ps.Name(p => p.Name.Suffix("searchable")).Index(FieldIndexOption.analyzed)) ) )) diff --git a/src/Nest/Domain/Mapping/Descriptors/AttachmentMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/AttachmentMappingDescriptor.cs index c5dbf999a46..7271397aca1 100644 --- a/src/Nest/Domain/Mapping/Descriptors/AttachmentMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/AttachmentMappingDescriptor.cs @@ -3,7 +3,7 @@ namespace Nest { - public class AttachmentMappingDescriptor + public class AttachmentMappingDescriptor where T : class { internal AttachmentMapping _Mapping = new AttachmentMapping(); diff --git a/src/Nest/Domain/Mapping/Descriptors/BooleanMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/BooleanMappingDescriptor.cs index 94891315f9c..addc78aab41 100644 --- a/src/Nest/Domain/Mapping/Descriptors/BooleanMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/BooleanMappingDescriptor.cs @@ -4,7 +4,7 @@ namespace Nest { - public class BooleanMappingDescriptor + public class BooleanMappingDescriptor where T : class { internal BooleanMapping _Mapping = new BooleanMapping(); @@ -63,5 +63,26 @@ public BooleanMappingDescriptor CopyTo(params Expression>[] o this._Mapping.CopyTo = objectPaths.Select(e => (PropertyPathMarker)e); return this; } + + public BooleanMappingDescriptor Path(MultiFieldMappingPath path) + { + this._Mapping.Path = path.Value; + return this; + } + + public BooleanMappingDescriptor Fields(Func, CorePropertiesDescriptor> fieldSelector) + { + fieldSelector.ThrowIfNull("fieldSelector"); + var properties = fieldSelector(new CorePropertiesDescriptor()); + foreach (var p in properties.Properties) + { + var value = p.Value as IElasticCoreType; + if (value == null) + continue; + + _Mapping.Fields[p.Key] = value; + } + return this; + } } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Descriptors/DateMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/DateMappingDescriptor.cs index 620ffcbc2b7..f6a25b9bb3e 100644 --- a/src/Nest/Domain/Mapping/Descriptors/DateMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/DateMappingDescriptor.cs @@ -3,7 +3,7 @@ namespace Nest { - public class DateMappingDescriptor + public class DateMappingDescriptor where T : class { internal DateMapping _Mapping = new DateMapping(); @@ -68,5 +68,25 @@ public DateMappingDescriptor IgnoreMalformed(bool ignoreMalformed = true) return this; } + public DateMappingDescriptor Path(MultiFieldMappingPath path) + { + this._Mapping.Path = path.Value; + return this; + } + + public DateMappingDescriptor Fields(Func, CorePropertiesDescriptor> fieldSelector) + { + fieldSelector.ThrowIfNull("fieldSelector"); + var properties = fieldSelector(new CorePropertiesDescriptor()); + foreach (var p in properties.Properties) + { + var value = p.Value as IElasticCoreType; + if (value == null) + continue; + + _Mapping.Fields[p.Key] = value; + } + return this; + } } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Descriptors/GenericMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/GenericMappingDescriptor.cs index 0d27b9707e2..30e65bda21f 100644 --- a/src/Nest/Domain/Mapping/Descriptors/GenericMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/GenericMappingDescriptor.cs @@ -3,7 +3,7 @@ namespace Nest { - public class GenericMappingDescriptor + public class GenericMappingDescriptor where T : class { internal GenericMapping _Mapping = new GenericMapping(); @@ -75,5 +75,26 @@ public GenericMappingDescriptor IncludeInAll(bool includeInAll = true) this._Mapping.IncludeInAll = includeInAll; return this; } + + public GenericMappingDescriptor Path(MultiFieldMappingPath path) + { + this._Mapping.Path = path.Value; + return this; + } + + public GenericMappingDescriptor Fields(Func, CorePropertiesDescriptor> fieldSelector) + { + fieldSelector.ThrowIfNull("fieldSelector"); + var properties = fieldSelector(new CorePropertiesDescriptor()); + foreach (var p in properties.Properties) + { + var value = p.Value as IElasticCoreType; + if (value == null) + continue; + + _Mapping.Fields[p.Key] = value; + } + return this; + } } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Descriptors/NumberMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/NumberMappingDescriptor.cs index cf12649c2e6..6eba10c1a9f 100644 --- a/src/Nest/Domain/Mapping/Descriptors/NumberMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/NumberMappingDescriptor.cs @@ -2,8 +2,8 @@ using System.Linq.Expressions; namespace Nest -{ - public class NumberMappingDescriptor +{ + public class NumberMappingDescriptor where T : class { internal NumberMapping _Mapping = new NumberMapping(); @@ -79,7 +79,27 @@ public NumberMappingDescriptor Coerce(bool coerce = true) { this._Mapping.Coerce = coerce; return this; + } + + public NumberMappingDescriptor Path(MultiFieldMappingPath path) + { + this._Mapping.Path = path.Value; + return this; + } + + public NumberMappingDescriptor Fields(Func, CorePropertiesDescriptor> fieldSelector) + { + fieldSelector.ThrowIfNull("fieldSelector"); + var properties = fieldSelector(new CorePropertiesDescriptor()); + foreach (var p in properties.Properties) + { + var value = p.Value as IElasticCoreType; + if (value == null) + continue; + + _Mapping.Fields[p.Key] = value; + } + return this; } - } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Descriptors/StringMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/StringMappingDescriptor.cs index a2f5305ad69..adcc3ccdfc2 100644 --- a/src/Nest/Domain/Mapping/Descriptors/StringMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/StringMappingDescriptor.cs @@ -3,8 +3,8 @@ using System.Linq.Expressions; namespace Nest -{ - public class StringMappingDescriptor +{ + public class StringMappingDescriptor where T : class { internal StringMapping _Mapping = new StringMapping(); @@ -118,6 +118,27 @@ public StringMappingDescriptor CopyTo(params Expression>[] ob { this._Mapping.CopyTo = objectPaths.Select(e => (PropertyPathMarker)e); return this; + } + + public StringMappingDescriptor Path(MultiFieldMappingPath path) + { + this._Mapping.Path = path.Value; + return this; + } + + public StringMappingDescriptor Fields(Func, CorePropertiesDescriptor> fieldSelector) + { + fieldSelector.ThrowIfNull("fieldSelector"); + var properties = fieldSelector(new CorePropertiesDescriptor()); + foreach (var p in properties.Properties) + { + var value = p.Value as IElasticCoreType; + if (value == null) + continue; + + _Mapping.Fields[p.Key] = value; + } + return this; } } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Types/BooleanMapping.cs b/src/Nest/Domain/Mapping/Types/BooleanMapping.cs index 5a10de72940..102f84c05b1 100644 --- a/src/Nest/Domain/Mapping/Types/BooleanMapping.cs +++ b/src/Nest/Domain/Mapping/Types/BooleanMapping.cs @@ -6,16 +6,11 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public class BooleanMapping : IElasticType, IElasticCoreType + public class BooleanMapping : MultiFieldMapping, IElasticType, IElasticCoreType { - - public PropertyNameMarker Name { get; set; } - - [JsonProperty("type")] - public virtual TypeNameMarker Type { get { return new TypeNameMarker { Name = "boolean" }; } } - - [JsonProperty("similarity")] - public string Similarity { get; set; } + public BooleanMapping():base("boolean") + { + } /// /// The name of the field that will be stored in the index. Defaults to the property/field name. @@ -35,9 +30,6 @@ public class BooleanMapping : IElasticType, IElasticCoreType [JsonProperty("null_value")] public bool? NullValue { get; set; } - [JsonProperty("include_in_all")] - public bool? IncludeInAll { get; set; } - [JsonProperty("copy_to")] public IEnumerable CopyTo { get; set; } } diff --git a/src/Nest/Domain/Mapping/Types/DateMapping.cs b/src/Nest/Domain/Mapping/Types/DateMapping.cs index db1620c53ee..dbff54428da 100644 --- a/src/Nest/Domain/Mapping/Types/DateMapping.cs +++ b/src/Nest/Domain/Mapping/Types/DateMapping.cs @@ -6,15 +6,11 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public class DateMapping : IElasticType, IElasticCoreType + public class DateMapping : MultiFieldMapping, IElasticType, IElasticCoreType { - public PropertyNameMarker Name { get; set; } - - [JsonProperty("type")] - public virtual TypeNameMarker Type { get { return new TypeNameMarker { Name = "date" }; } } - - [JsonProperty("similarity")] - public string Similarity { get; set; } + public DateMapping():base("date") + { + } /// /// The name of the field that will be stored in the index. Defaults to the property/field name. @@ -40,9 +36,6 @@ public class DateMapping : IElasticType, IElasticCoreType [JsonProperty("null_value")] public DateTime? NullValue { get; set; } - [JsonProperty("include_in_all")] - public bool? IncludeInAll { get; set; } - [JsonProperty("ignore_malformed")] public bool? IgnoreMalformed { get; set; } diff --git a/src/Nest/Domain/Mapping/Types/GenericMapping.cs b/src/Nest/Domain/Mapping/Types/GenericMapping.cs index ac729c61dbb..8edaf1dd237 100644 --- a/src/Nest/Domain/Mapping/Types/GenericMapping.cs +++ b/src/Nest/Domain/Mapping/Types/GenericMapping.cs @@ -10,16 +10,11 @@ namespace Nest /// in order to specify "{dynamic_template}" the type, or if you have some plugin that exposes a new type. /// [JsonObject(MemberSerialization.OptIn)] - public class GenericMapping : IElasticType, IElasticCoreType + public class GenericMapping : MultiFieldMapping, IElasticType, IElasticCoreType { - - public PropertyNameMarker Name { get; set; } - - [JsonProperty("type")] - public TypeNameMarker Type { get; set; } - - [JsonProperty("similarity")] - public string Similarity { get; set; } + public GenericMapping():base(null) + { + } /// /// The name of the field that will be stored in the index. Defaults to the property/field name. @@ -39,9 +34,6 @@ public class GenericMapping : IElasticType, IElasticCoreType [JsonProperty("boost")] public double? Boost { get; set; } - [JsonProperty("include_in_all")] - public bool? IncludeInAll { get; set; } - [JsonProperty("term_vector")] public string TermVector { get; set; } diff --git a/src/Nest/Domain/Mapping/Types/MultiFieldMapping.cs b/src/Nest/Domain/Mapping/Types/MultiFieldMapping.cs index 6780dc92398..b87f627f61b 100644 --- a/src/Nest/Domain/Mapping/Types/MultiFieldMapping.cs +++ b/src/Nest/Domain/Mapping/Types/MultiFieldMapping.cs @@ -8,6 +8,19 @@ namespace Nest [JsonObject(MemberSerialization.OptIn)] public class MultiFieldMapping : IElasticType { + private readonly TypeNameMarker _defaultType; + + public MultiFieldMapping() + : this("multi_field") + { + this.Fields = new Dictionary(); + } + + protected MultiFieldMapping(TypeNameMarker defaultType) + { + _defaultType = defaultType; + } + public PropertyNameMarker Name { get; set; } private TypeNameMarker _typeOverride; @@ -15,7 +28,7 @@ public class MultiFieldMapping : IElasticType [JsonProperty("type")] public virtual TypeNameMarker Type { - get { return _typeOverride ?? new TypeNameMarker { Name = "multi_field" }; } + get { return _typeOverride ?? _defaultType; } set { _typeOverride = value; } } @@ -28,14 +41,8 @@ public virtual TypeNameMarker Type [JsonProperty("include_in_all")] public bool? IncludeInAll { get; set; } - [JsonProperty("fields"), JsonConverter(typeof(ElasticCoreTypeConverter))] + [JsonProperty("fields", DefaultValueHandling = DefaultValueHandling.Ignore), JsonConverter(typeof(ElasticCoreTypeConverter))] public IDictionary Fields { get; set; } - - - public MultiFieldMapping() - { - this.Fields = new Dictionary(); - } } public class MultiFieldMappingPath diff --git a/src/Nest/Domain/Mapping/Types/NumberMapping.cs b/src/Nest/Domain/Mapping/Types/NumberMapping.cs index 69a2167f3d3..b94f77d77dd 100644 --- a/src/Nest/Domain/Mapping/Types/NumberMapping.cs +++ b/src/Nest/Domain/Mapping/Types/NumberMapping.cs @@ -1,54 +1,47 @@ using System.Collections.Generic; -using Newtonsoft.Json; -using System; +using Newtonsoft.Json; +using System; using Newtonsoft.Json.Converters; -namespace Nest -{ - [JsonObject(MemberSerialization.OptIn)] - public class NumberMapping : IElasticType, IElasticCoreType - { - public PropertyNameMarker Name { get; set; } - - private TypeNameMarker __type; - [JsonProperty("type")] - public virtual TypeNameMarker Type { get { return (TypeNameMarker)(__type ?? "double"); } set { __type = value; } } - - [JsonProperty("similarity")] - public string Similarity { get; set; } - - /// - /// The name of the field that will be stored in the index. Defaults to the property/field name. - /// - [JsonProperty("index_name")] - public string IndexName { get; set; } - - [JsonProperty("store")] - public bool? Store { get; set; } - - [JsonProperty("index"), JsonConverter(typeof(StringEnumConverter))] - public NonStringIndexOption? Index { get; set; } - - [JsonProperty("precision_step")] - public int? PrecisionStep { get; set; } - - [JsonProperty("boost")] - public double? Boost { get; set; } - - [JsonProperty("null_value")] - public double? NullValue { get; set; } - +namespace Nest +{ + [JsonObject(MemberSerialization.OptIn)] + public class NumberMapping : MultiFieldMapping, IElasticType, IElasticCoreType + { + public NumberMapping() + : base("double") + { + } + + /// + /// The name of the field that will be stored in the index. Defaults to the property/field name. + /// + [JsonProperty("index_name")] + public string IndexName { get; set; } + + [JsonProperty("store")] + public bool? Store { get; set; } + + [JsonProperty("index"), JsonConverter(typeof(StringEnumConverter))] + public NonStringIndexOption? Index { get; set; } + + [JsonProperty("precision_step")] + public int? PrecisionStep { get; set; } + + [JsonProperty("boost")] + public double? Boost { get; set; } + + [JsonProperty("null_value")] + public double? NullValue { get; set; } + [JsonProperty("doc_values")] - public bool? DocValues { get; set; } - - [JsonProperty("include_in_all")] - public bool? IncludeInAll { get; set; } - + public bool? DocValues { get; set; } + [JsonProperty("ignore_malformed")] public bool? IgnoreMalformed { get; set; } - [JsonProperty("coerce")] - public bool? Coerce { get; set; } - - } + [JsonProperty("coerce")] + public bool? Coerce { get; set; } + + } } \ No newline at end of file diff --git a/src/Nest/Domain/Mapping/Types/StringMapping.cs b/src/Nest/Domain/Mapping/Types/StringMapping.cs index a70dcca8663..1bb229dbabf 100644 --- a/src/Nest/Domain/Mapping/Types/StringMapping.cs +++ b/src/Nest/Domain/Mapping/Types/StringMapping.cs @@ -6,16 +6,11 @@ namespace Nest { [JsonObject(MemberSerialization.OptIn)] - public class StringMapping : IElasticType, IElasticCoreType - { - [JsonProperty("type")] - public virtual TypeNameMarker Type { get { return new TypeNameMarker { Name = "string" }; } } - - //[JsonProperty(PropertyName = "name")] - public PropertyNameMarker Name { get; set; } - - [JsonProperty("similarity")] - public string Similarity { get; set; } + public class StringMapping : MultiFieldMapping, IElasticType, IElasticCoreType + { + public StringMapping():base("string") + { + } /// /// The name of the field that will be stored in the index. Defaults to the property/field name. @@ -62,9 +57,6 @@ public class StringMapping : IElasticType, IElasticCoreType [JsonProperty("doc_values")] public bool? DocValues { get; set; } - [JsonProperty("include_in_all")] - public bool? IncludeInAll { get; set; } - [JsonProperty("position_offset_gap")] public int? PositionOffsetGap { get; set; } diff --git a/src/Nest/Resolvers/Converters/ElasticTypeConverter.cs b/src/Nest/Resolvers/Converters/ElasticTypeConverter.cs index 6360489f8f6..1776f639bb6 100644 --- a/src/Nest/Resolvers/Converters/ElasticTypeConverter.cs +++ b/src/Nest/Resolvers/Converters/ElasticTypeConverter.cs @@ -22,7 +22,6 @@ private IElasticType GetTypeFromJObject(JObject po, JsonSerializer serializer) { JToken typeToken; JToken propertiesToken; - JToken fieldsToken; var type = string.Empty; var hasType = po.TryGetValue("type", out typeToken); @@ -31,11 +30,6 @@ private IElasticType GetTypeFromJObject(JObject po, JsonSerializer serializer) else if (po.TryGetValue("properties", out propertiesToken)) type = "object"; - var originalType = type; - var hasFields = po.TryGetValue("fields", out fieldsToken); - if (hasFields) - type = "multi_field"; - serializer.TypeNameHandling = TypeNameHandling.None; switch (type) @@ -60,9 +54,7 @@ private IElasticType GetTypeFromJObject(JObject po, JsonSerializer serializer) case "nested": return serializer.Deserialize(po.CreateReader(), typeof(NestedObjectMapping)) as NestedObjectMapping; case "multi_field": - var m =serializer.Deserialize(po.CreateReader(), typeof(MultiFieldMapping)) as MultiFieldMapping; - m.Type = originalType; - return m; + return serializer.Deserialize(po.CreateReader(), typeof(MultiFieldMapping)) as MultiFieldMapping; case "ip": return serializer.Deserialize(po.CreateReader(), typeof(IPMapping)) as IPMapping; case "geo_point": diff --git a/src/Nest/Resolvers/ElasticContractResolver.cs b/src/Nest/Resolvers/ElasticContractResolver.cs index 6969033ce5f..4c7d23fba05 100644 --- a/src/Nest/Resolvers/ElasticContractResolver.cs +++ b/src/Nest/Resolvers/ElasticContractResolver.cs @@ -156,6 +156,20 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ { var property = base.CreateProperty(member, memberSerialization); + // Skip serialization of empty collections that has DefaultValueHandling set to Ignore. + if (property.DefaultValueHandling.HasValue + && property.DefaultValueHandling.Value == DefaultValueHandling.Ignore + && !typeof(string).IsAssignableFrom(property.PropertyType) + && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) + { + Predicate shouldSerialize = obj => + { + var collection = property.ValueProvider.GetValue(obj) as ICollection; + return collection == null || collection.Count != 0; + }; + property.ShouldSerialize = property.ShouldSerialize == null ? shouldSerialize : (o => property.ShouldSerialize(o) && shouldSerialize(o)); + } + var attributes = member.GetCustomAttributes(typeof(IElasticPropertyAttribute), false); if (attributes == null || !attributes.Any()) return property; diff --git a/src/Tests/Nest.Tests.Integration/Core/GetFieldMapping/GetFieldMappingTests.cs b/src/Tests/Nest.Tests.Integration/Core/GetFieldMapping/GetFieldMappingTests.cs index 93ac35e8542..f63bcd9fe39 100644 --- a/src/Tests/Nest.Tests.Integration/Core/GetFieldMapping/GetFieldMappingTests.cs +++ b/src/Tests/Nest.Tests.Integration/Core/GetFieldMapping/GetFieldMappingTests.cs @@ -111,7 +111,7 @@ public void SpecialFields_AreInspectable() .SearchAnalyzer("default") .StoreTermVectorPositions() ) - .IndexField(i=>i.Enabled(false).Store()) + .IndexField(i=>i.Enabled(true).Store(true)) .SizeField(i=>i.Enabled(false).Store(false)) .IdField(i => i .Index("not_analyzed") @@ -168,7 +168,8 @@ public void SpecialFields_AreInspectable() var indexField = fieldMappingResponse.MappingFor("_index") as IndexFieldMapping; indexField.Should().NotBeNull(); - indexField.Enabled.Should().BeFalse(); + indexField.Enabled.Should().BeTrue(); + indexField.Store.Should().BeTrue(); var typeField = fieldMappingResponse.MappingFor("_type") as TypeFieldMapping; typeField.Should().NotBeNull();