Skip to content

Commit 50c60bf

Browse files
committed
Merge pull request #1290 from elastic/fix/901
fixes enums being skipped when calling MapFromAttributes()
2 parents 36515bb + ed65a70 commit 50c60bf

File tree

10 files changed

+175
-10
lines changed

10 files changed

+175
-10
lines changed

src/Nest/DSL/PutMappingDescriptor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,11 @@ public PutMappingDescriptor<T> InitializeUsing(RootObjectMapping rootObjectMappi
9999
}
100100

101101
/// <summary>
102-
/// Convenience method to map from most of the object from the attributes/properties.
103-
/// Later calls can override whatever is set is by this call.
104-
/// This helps mapping all the ints as ints, floats as floats etcetera withouth having to be overly verbose in your fluent mapping
102+
/// Convenience method to map as much as it can based on ElasticType attributes set on the type.
103+
/// <pre>This method also automatically sets up mappings for known values types (int, long, double, datetime, etcetera)</pre>
104+
/// <pre>Class types default to object and Enums to int</pre>
105+
/// <pre>Later calls can override whatever is set is by this call.</pre>
105106
/// </summary>
106-
/// <returns></returns>
107107
public PutMappingDescriptor<T> MapFromAttributes(int maxRecursion = 0)
108108
{
109109
//TODO no longer needed when we have an IPutMappingRequest

src/Nest/Resolvers/Writers/TypeMappingWriter.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ public class TypeMappingWriter
1515
private readonly Type _type;
1616
private readonly IConnectionSettingsValues _connectionSettings;
1717
private readonly NestSerializer _elasticSerializer;
18+
19+
private readonly static string _noFieldTypeMessage =
20+
"Property {0} on type {1} has an ElasticProperty attribute but its FieldType (Type = ) can not be inferred and is not set explicitly while calling MapFromAttributes";
21+
1822
private ElasticInferrer Infer { get; set; }
1923

2024
private int MaxRecursion { get; set; }
@@ -136,7 +140,7 @@ internal void WriteProperties(JsonWriter jsonWriter)
136140

137141
var propertyName = this.Infer.PropertyName(p);
138142
var type = GetElasticSearchType(att, p);
139-
143+
140144
if (type == null) //could not get type from attribute or infer from CLR type.
141145
continue;
142146

@@ -194,6 +198,11 @@ private string GetElasticSearchType(IElasticPropertyAttribute att, PropertyInfo
194198
if (fieldType == null || fieldType == FieldType.None)
195199
{
196200
fieldType = this.GetFieldTypeFromType(p.PropertyType);
201+
if (fieldType == null && att != null)
202+
{
203+
var message = _noFieldTypeMessage.F(p.Name, this._type.Name);
204+
throw new DslException(message);
205+
}
197206
}
198207

199208
return this.GetElasticSearchTypeFromFieldType(fieldType);
@@ -234,8 +243,8 @@ private string GetElasticSearchTypeFromFieldType(FieldType? fieldType)
234243
return "boolean";
235244
case FieldType.Completion:
236245
return "completion";
237-
case FieldType.Nested:
238-
return "nested";
246+
case FieldType.Nested:
247+
return "nested";
239248
case FieldType.Object:
240249
return "object";
241250
default:
@@ -255,6 +264,9 @@ private string GetElasticSearchTypeFromFieldType(FieldType? fieldType)
255264
if (propertyType == typeof(string))
256265
return FieldType.String;
257266

267+
if (propertyType.IsEnum)
268+
return FieldType.Integer;
269+
258270
if (propertyType.IsValueType)
259271
{
260272
switch (propertyType.Name)
@@ -284,7 +296,7 @@ private static Type GetUnderlyingType(Type type)
284296
if (type.IsArray)
285297
return type.GetElementType();
286298

287-
if (type.IsGenericType && type.GetGenericArguments().Length == 1 && (type.GetInterface("IEnumerable") != null || Nullable.GetUnderlyingType(type) != null))
299+
if (type.IsGenericType && type.GetGenericArguments().Length == 1 && (type.GetInterface("IEnumerable") != null || Nullable.GetUnderlyingType(type) != null))
288300
return type.GetGenericArguments()[0];
289301

290302
return type;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"myclass": {
3+
"properties": {
4+
"myEnum": {
5+
"index": "not_analyzed",
6+
"type": "string"
7+
}
8+
}
9+
}
10+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Nest.Tests.Unit.Core.Map.Enums
10+
{
11+
[TestFixture]
12+
public class EnumMappingTests : BaseJsonTests
13+
{
14+
private class MyClass
15+
{
16+
public MyEnum MyEnum { get; set; }
17+
}
18+
19+
private enum MyEnum
20+
{
21+
Value1,
22+
Value2
23+
}
24+
25+
[Test]
26+
public void EnumShouldMapToIntByDefault()
27+
{
28+
var result = this._client.Map<MyClass>(m => m.MapFromAttributes());
29+
this.JsonEquals(result.ConnectionStatus.Request, MethodBase.GetCurrentMethod());
30+
}
31+
32+
[Test]
33+
public void EnumCanBeOverriddenAfterMapFromAttributes()
34+
{
35+
var result = this._client.Map<MyClass>(m => m
36+
.MapFromAttributes()
37+
.Properties(props=>props
38+
.String(s=>s
39+
.Name(p=>p.MyEnum)
40+
.Index(FieldIndexOption.NotAnalyzed)
41+
)
42+
)
43+
);
44+
this.JsonEquals(result.ConnectionStatus.Request, MethodBase.GetCurrentMethod());
45+
}
46+
47+
}
48+
49+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"myclass": {
3+
"properties": {
4+
"myEnum": {
5+
"type": "integer"
6+
}
7+
}
8+
}
9+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using FluentAssertions;
9+
10+
namespace Nest.Tests.Unit.Core.Map.Structs
11+
{
12+
[TestFixture]
13+
public class StructMappingTests : BaseJsonTests
14+
{
15+
private class MyClass
16+
{
17+
public MyStruct Struct { get; set; }
18+
}
19+
20+
private class MyClass2
21+
{
22+
[ElasticProperty(Analyzer = "default")]
23+
public MyStruct StructProperty { get; set; }
24+
}
25+
26+
private struct MyStruct
27+
{
28+
public string Object { get; set; }
29+
}
30+
31+
[Test]
32+
public void StructWithNoAttributeSetIsIgnored()
33+
{
34+
//unknow value types are not handled by default by MapFromAttributes()
35+
var result = this._client.Map<MyClass>(m => m.MapFromAttributes());
36+
this.JsonEquals(result.ConnectionStatus.Request, MethodBase.GetCurrentMethod());
37+
}
38+
39+
[Test]
40+
public void StructWithAttributeButNoTypeInformationThrows()
41+
{
42+
//unknown value types with missing FieldType information in the attribute should throw an exception
43+
44+
//example
45+
46+
//Nest.DslException : Property Struct on type MyClass2 <continued>
47+
//has an ElasticProperty attribute but its FieldType (Type = ) can not be inferred <continued>
48+
//and is not set explicitly while calling MapFromAttributes
49+
50+
var e = Assert.Throws<DslException>(() =>
51+
{
52+
var result = this._client.Map<MyClass2>(m => m.MapFromAttributes());
53+
this.JsonEquals(result.ConnectionStatus.Request, MethodBase.GetCurrentMethod());
54+
});
55+
56+
e.Message.Should().EndWith("while calling MapFromAttributes");
57+
e.Message.Should().Contain("StructProperty");
58+
}
59+
60+
}
61+
62+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"myclass2": {
3+
"properties": {
4+
}
5+
}
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"myclass": {
3+
"properties": {
4+
}
5+
}
6+
}

src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
<Compile Include="Core\Indices\Analysis\TokenFilters\TokenFilterTests.cs" />
108108
<Compile Include="Core\Indices\Similarity\SimilarityTests.cs" />
109109
<Compile Include="Core\Map\CustomMapping\ImagePluginMappingTests.cs" />
110+
<Compile Include="Core\Map\Enums\EnumMappingTests.cs" />
110111
<Compile Include="Core\Map\GenericTypes\GenericTypeMappingTests.cs" />
111112
<Compile Include="Core\Map\GeoShape\GeoShapeMappingTests.cs" />
112113
<Compile Include="Core\Map\GetMappingSerializationTests.cs" />
@@ -176,6 +177,12 @@
176177
<None Include="Core\Map\CustomMapping\RepresentUnknowImageMappingPlugin.json">
177178
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
178179
</None>
180+
<None Include="Core\Map\Enums\EnumCanBeOverriddenAfterMapFromAttributes.json">
181+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
182+
</None>
183+
<None Include="Core\Map\Enums\EnumShouldMapToIntByDefault.json">
184+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
185+
</None>
179186
<None Include="Core\Map\GenericTypes\GenericTypeMapping.json">
180187
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
181188
</None>
@@ -392,7 +399,7 @@
392399
<Compile Include="Reproduce\Reproduce1146Tests.cs" />
393400
<Compile Include="Reproduce\Reproduce629Tests.cs" />
394401
<Compile Include="Reproduce\Reproduce1187Tests.cs" />
395-
<Compile Include="Reproduce\Reproduce991Tests.cs" />
402+
<Compile Include="Reproduce\Reproduce901Tests.cs" />
396403
<Compile Include="Reproduce\Reproduce990Tests.cs" />
397404
<Compile Include="Reproduce\Reproduce974Tests.cs" />
398405
<Compile Include="Reproduce\Reproduce928Tests.cs" />
@@ -819,6 +826,9 @@
819826
<None Include="Reproduce\Issue1199Mapping.json">
820827
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
821828
</None>
829+
<None Include="Reproduce\EnumQueryDefaultsToInt.json">
830+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
831+
</None>
822832
<None Include="Reproduce\Issue928.json">
823833
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
824834
</None>

src/Tests/Nest.Tests.Unit/Reproduce/Reproduce991Tests.cs renamed to src/Tests/Nest.Tests.Unit/Reproduce/Reproduce901Tests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Nest.Tests.Unit.Reproduce
1212
/// tests to reproduce reported errors
1313
/// </summary>
1414
[TestFixture]
15-
public class Reproduce991Tests : BaseJsonTests
15+
public class Reproduce901Tests : BaseJsonTests
1616
{
1717
private class MyClass
1818
{
@@ -32,5 +32,6 @@ public void EnumQueryDefaultsToInt()
3232
.Query(q => q.Term(p => p.MyEnum, MyEnum.Value2));
3333
this.JsonEquals(query, MethodBase.GetCurrentMethod());
3434
}
35+
3536
}
3637
}

0 commit comments

Comments
 (0)