Skip to content

Commit a6de6df

Browse files
committed
Fix duplicate properties from being mapped and ensure AutoMap is idempotent
Closes #1852
1 parent 1aa18c3 commit a6de6df

File tree

8 files changed

+1085
-885
lines changed

8 files changed

+1085
-885
lines changed

src/Nest/CommonAbstractions/SerializationBehavior/GenericJsonConverters/VerbatimDictionaryKeysConverter.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Linq;
23
using System.Collections;
34
using System.Collections.Generic;
45
using System.Globalization;
@@ -24,13 +25,13 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
2425

2526
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
2627
{
27-
2828
var dictionary = value as IDictionary;
2929
if (dictionary == null) return;
3030

3131
var settings = serializer.GetConnectionSettings();
3232

33-
writer.WriteStartObject();
33+
var seenEntries = new Dictionary<string, object>();
34+
3435
foreach (DictionaryEntry entry in dictionary)
3536
{
3637
if (entry.Value == null && serializer.NullValueHandling == NullValueHandling.Ignore)
@@ -64,11 +65,15 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
6465
else
6566
key = Convert.ToString(entry.Key, CultureInfo.InvariantCulture);
6667

67-
writer.WritePropertyName(key);
68-
serializer.Serialize(writer, entry.Value);
69-
68+
seenEntries[key] = entry.Value;
7069
}
7170

71+
writer.WriteStartObject();
72+
foreach(var entry in seenEntries)
73+
{
74+
writer.WritePropertyName(entry.Key);
75+
serializer.Serialize(writer, entry.Value);
76+
}
7277
writer.WriteEndObject();
7378
}
7479
}

src/Nest/Indices/MappingManagement/PutMapping/PutMappingRequest.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,8 @@ public PutMappingDescriptor(IndexName index, TypeName type) : base(r=>r.Required
135135
/// <pre>Class types default to object and Enums to int</pre>
136136
/// <pre>Later calls can override whatever is set is by this call.</pre>
137137
/// </summary>
138-
public PutMappingDescriptor<T> AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) => Assign(a =>
139-
{
140-
a.Properties = a.Properties ?? new Properties();
141-
var autoProperties = new PropertyWalker(typeof(T), visitor, maxRecursion).GetProperties();
142-
foreach (var autoProperty in (IEnumerable<KeyValuePair<PropertyName, IProperty>>)autoProperties)
143-
a.Properties[autoProperty.Key] = autoProperty.Value;
144-
});
138+
public PutMappingDescriptor<T> AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) =>
139+
Assign(a => a.Properties = a.Properties.AutoMap<T>(visitor, maxRecursion));
145140

146141
/// <inheritdoc/>
147142
public PutMappingDescriptor<T> AutoMap(int maxRecursion) => AutoMap(null, maxRecursion);

src/Nest/Mapping/TypeMapping.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ public class TypeMappingDescriptor<T> : DescriptorBase<TypeMappingDescriptor<T>,
140140
/// <pre>Class types default to object and Enums to int</pre>
141141
/// <pre>Later calls can override whatever is set is by this call.</pre>
142142
/// </summary>
143-
public TypeMappingDescriptor<T> AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) =>
144-
Assign(a => a.Properties = new PropertyWalker(typeof(T), visitor, maxRecursion).GetProperties());
143+
public TypeMappingDescriptor<T> AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) =>
144+
Assign(a => a.Properties = a.Properties.AutoMap<T>(visitor, maxRecursion));
145145

146146
/// <inheritdoc/>
147147
public TypeMappingDescriptor<T> AutoMap(int maxRecursion) => AutoMap(null, maxRecursion);

src/Nest/Mapping/Types/Complex/Object/ObjectProperty.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,8 @@ public TDescriptor Path(string path) =>
8383
public TDescriptor Properties(Func<PropertiesDescriptor<TChild>, IPromise<IProperties>> selector) =>
8484
Assign(a => a.Properties = selector?.Invoke(new PropertiesDescriptor<TChild>(a.Properties))?.Value);
8585

86-
public TDescriptor AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) => Assign(a =>
87-
{
88-
a.Properties = a.Properties ?? new Properties();
89-
var autoProperties = new PropertyWalker(typeof(TChild), visitor, maxRecursion).GetProperties();
90-
foreach (var autoProperty in (IEnumerable<KeyValuePair<PropertyName, IProperty>>)autoProperties)
91-
a.Properties[autoProperty.Key] = autoProperty.Value;
92-
});
86+
public TDescriptor AutoMap(IPropertyVisitor visitor = null, int maxRecursion = 0) =>
87+
Assign(a => a.Properties = a.Properties.AutoMap<TChild>(visitor, maxRecursion));
9388

9489
public TDescriptor AutoMap(int maxRecursion) => AutoMap(null, maxRecursion);
9590
}

src/Nest/Mapping/Types/Properties.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,25 @@ private PropertiesDescriptor<T> SetProperty(IProperty type)
113113
return this.Assign(a => a[type.Name] = type);
114114
}
115115
}
116+
117+
internal static class PropertiesExtensions
118+
{
119+
internal static IProperties AutoMap<T>(this IProperties existingProperties, IPropertyVisitor visitor = null, int maxRecursion = 0)
120+
where T : class
121+
{
122+
var properties = new Properties();
123+
var autoProperties = new PropertyWalker(typeof(T), visitor, maxRecursion).GetProperties();
124+
foreach (var autoProperty in (IEnumerable<KeyValuePair<PropertyName, IProperty>>)autoProperties)
125+
properties[autoProperty.Key] = autoProperty.Value;
126+
127+
// Existing/manually mapped properties always take precedence
128+
if (existingProperties != null)
129+
{
130+
foreach (var existing in (IEnumerable<KeyValuePair<PropertyName, IProperty>>)existingProperties)
131+
properties[existing.Key] = existing.Value;
132+
}
133+
134+
return properties;
135+
}
136+
}
116137
}

0 commit comments

Comments
 (0)