Skip to content

Commit 39a774f

Browse files
[Backport master] Implement version field type (#5250)
* Implement version field type (#5200) * Implement version field type * Fix failing test * Add skip version to test * Fixup namespace for master Co-authored-by: Steve Gordon <sgordon@hotmail.co.uk>
1 parent 0b784b1 commit 39a774f

File tree

14 files changed

+160
-4
lines changed

14 files changed

+160
-4
lines changed

src/Nest/Mapping/DynamicTemplate/SingleMapping.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ public IProperty ConstantKeyword(Func<ConstantKeywordPropertyDescriptor<T>, ICon
148148
/// <inheritdoc />
149149
public IProperty Wildcard(Func<WildcardPropertyDescriptor<T>, IWildcardProperty> selector) =>
150150
selector?.Invoke(new WildcardPropertyDescriptor<T>());
151+
152+
/// <inheritdoc />
153+
public IProperty Version(Func<VersionPropertyDescriptor<T>, IVersionProperty> selector) =>
154+
selector?.Invoke(new VersionPropertyDescriptor<T>());
151155

152156
#pragma warning disable CS3001 // Argument type is not CLS-compliant
153157
public IProperty Scalar(Expression<Func<T, int>> field, Func<NumberPropertyDescriptor<T>, INumberProperty> selector = null) =>

src/Nest/Mapping/Types/FieldType.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,11 @@ public enum FieldType
154154

155155
[EnumMember(Value = "point")]
156156
Point,
157+
158+
/// <summary>
159+
/// Version field type for storing semver compatible version numbers.
160+
/// </summary>
161+
[EnumMember(Value = "version")]
162+
Version
157163
}
158164
}

src/Nest/Mapping/Types/Properties.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ TReturnType Nested<TChild>(Func<NestedPropertyDescriptor<T, TChild>, INestedProp
151151

152152
/// <inheritdoc cref="IWildcardProperty"/>
153153
TReturnType Wildcard(Func<WildcardPropertyDescriptor<T>, IWildcardProperty> selector);
154+
155+
/// <inheritdoc cref="IVersionProperty"/>
156+
TReturnType Version(Func<VersionPropertyDescriptor<T>, IVersionProperty> selector);
154157
}
155158

156159
public partial class PropertiesDescriptor<T> where T : class
@@ -263,8 +266,10 @@ public PropertiesDescriptor<T> ConstantKeyword(Func<ConstantKeywordPropertyDescr
263266
SetProperty(selector);
264267

265268
/// <inheritdoc cref="IWildcardProperty"/>
266-
public PropertiesDescriptor<T> Wildcard(Func<WildcardPropertyDescriptor<T>, IWildcardProperty> selector) =>
267-
SetProperty(selector);
269+
public PropertiesDescriptor<T> Wildcard(Func<WildcardPropertyDescriptor<T>, IWildcardProperty> selector) => SetProperty(selector);
270+
271+
/// <inheritdoc cref="IVersionProperty"/>
272+
public PropertiesDescriptor<T> Version(Func<VersionPropertyDescriptor<T>, IVersionProperty> selector) => SetProperty(selector);
268273

269274
/// <summary>
270275
/// Map a custom property.

src/Nest/Mapping/Types/PropertyFormatter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public IProperty Deserialize(ref JsonReader reader, IJsonFormatterResolver forma
9797
case FieldType.Histogram: return Deserialize<HistogramProperty>(ref segmentReader, formatterResolver);
9898
case FieldType.ConstantKeyword: return Deserialize<ConstantKeywordProperty>(ref segmentReader, formatterResolver);
9999
case FieldType.Wildcard: return Deserialize<WildcardProperty>(ref segmentReader, formatterResolver);
100+
case FieldType.Version: return Deserialize<VersionProperty>(ref segmentReader, formatterResolver);
100101
case FieldType.None:
101102
// no "type" field in the property mapping, or FieldType enum could not be parsed from typeString
102103
return Deserialize<ObjectProperty>(ref segmentReader, formatterResolver);
@@ -217,6 +218,9 @@ public void Serialize(ref JsonWriter writer, IProperty value, IJsonFormatterReso
217218
case IGenericProperty genericProperty:
218219
Serialize(ref writer, genericProperty, formatterResolver);
219220
break;
221+
case IVersionProperty versionProperty:
222+
Serialize(ref writer, versionProperty, formatterResolver);
223+
break;
220224
default:
221225
var formatter = formatterResolver.GetFormatter<object>();
222226
formatter.Serialize(ref writer, value, formatterResolver);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
namespace Nest
6+
{
7+
public class VersionAttribute : ElasticsearchPropertyAttributeBase, IVersionProperty
8+
{
9+
public VersionAttribute() : base(FieldType.Version) { }
10+
11+
private IVersionProperty Self => this;
12+
}
13+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Diagnostics;
6+
using Nest.Utf8Json;
7+
8+
namespace Nest
9+
{
10+
/// <summary>
11+
/// A version field can index/store semver version numbers.
12+
/// </summary>
13+
[InterfaceDataContract]
14+
public interface IVersionProperty : IProperty
15+
{
16+
}
17+
18+
/// <inheritdoc cref="IVersionProperty"/>
19+
[DebuggerDisplay("{DebugDisplay}")]
20+
public class VersionProperty : PropertyBase, IVersionProperty
21+
{
22+
public VersionProperty() : base(FieldType.Version) { }
23+
}
24+
25+
/// <inheritdoc cref="IVersionProperty" />
26+
[DebuggerDisplay("{DebugDisplay}")]
27+
public class VersionPropertyDescriptor<T>
28+
: PropertyDescriptorBase<VersionPropertyDescriptor<T>, IVersionProperty, T>, IVersionProperty
29+
where T : class
30+
{
31+
public VersionPropertyDescriptor() : base(FieldType.Version) { }
32+
}
33+
}

src/Nest/Mapping/Visitor/IMappingVisitor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ public interface IMappingVisitor
7171
void Visit(IHistogramProperty property);
7272

7373
void Visit(IConstantKeywordProperty property);
74+
75+
void Visit(IVersionProperty property);
7476
}
7577

7678
public class NoopMappingVisitor : IMappingVisitor
@@ -140,5 +142,7 @@ public virtual void Visit(IFlattenedProperty property) { }
140142
public virtual void Visit(IHistogramProperty property) { }
141143

142144
public virtual void Visit(IConstantKeywordProperty property) { }
145+
146+
public virtual void Visit(IVersionProperty property) { }
143147
}
144148
}

src/Nest/Mapping/Visitor/IPropertyVisitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public interface IPropertyVisitor
7676

7777
void Visit(IWildcardProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);
7878

79+
void Visit(IVersionProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);
80+
7981
IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);
8082

8183
bool SkipProperty(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute);

src/Nest/Mapping/Visitor/MappingWalker.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ public void Accept(IProperties properties)
273273
_visitor.Visit(t);
274274
});
275275
break;
276+
case FieldType.Version:
277+
Visit<IVersionProperty>(field, t =>
278+
{
279+
_visitor.Visit(t);
280+
});
281+
break;
276282
case FieldType.None:
277283
continue;
278284
}

src/Nest/Mapping/Visitor/NoopPropertyVisitor.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public virtual void Visit(IFieldAliasProperty type, PropertyInfo propertyInfo, E
7676

7777
public virtual void Visit(IWildcardProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) { }
7878

79+
public virtual void Visit(IVersionProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) { }
80+
7981
public virtual IProperty Visit(PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute) => null;
8082

8183
public virtual void Visit(IProperty type, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
@@ -168,7 +170,7 @@ public virtual void Visit(IProperty type, PropertyInfo propertyInfo, Elasticsear
168170
break;
169171
case IPointProperty point:
170172
Visit(point, propertyInfo, attribute);
171-
break;
173+
break;
172174
case ISearchAsYouTypeProperty searchAsYouType:
173175
Visit(searchAsYouType, propertyInfo, attribute);
174176
break;
@@ -178,6 +180,9 @@ public virtual void Visit(IProperty type, PropertyInfo propertyInfo, Elasticsear
178180
case IFieldAliasProperty fieldAlias:
179181
Visit(fieldAlias, propertyInfo, attribute);
180182
break;
183+
case IVersionProperty version:
184+
Visit(version, propertyInfo, attribute);
185+
break;
181186
}
182187
}
183188
}

src/Nest/Search/FieldCapabilities/FieldCapabilitiesResponse.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public class FieldTypes : IsADictionaryBase<string, FieldCapabilities>
5353
public FieldCapabilities Integer => BackingDictionary.TryGetValue("integer", out var f) ? f : null;
5454
public FieldCapabilities IntegerRange => BackingDictionary.TryGetValue("integer_range", out var f) ? f : null;
5555
public FieldCapabilities Ip => BackingDictionary.TryGetValue("ip", out var f) ? f : null;
56-
5756
public FieldCapabilities Keyword => BackingDictionary.TryGetValue("keyword", out var f) ? f : null;
5857
public FieldCapabilities Long => BackingDictionary.TryGetValue("long", out var f) ? f : null;
5958
public FieldCapabilities LongRange => BackingDictionary.TryGetValue("long_range", out var f) ? f : null;
@@ -71,6 +70,7 @@ public class FieldTypes : IsADictionaryBase<string, FieldCapabilities>
7170
public FieldCapabilities Uid => BackingDictionary.TryGetValue("_uid", out var f) ? f : null;
7271
public FieldCapabilities ParentJoin => BackingDictionary.TryGetValue("_parent_join", out var f) ? f : null;
7372
public FieldCapabilities Version => BackingDictionary.TryGetValue("_version", out var f) ? f : null;
73+
public FieldCapabilities VersionField => BackingDictionary.TryGetValue("version", out var f) ? f : null;
7474
}
7575

7676
public class FieldCapabilities

tests/Tests/Indices/MappingManagement/GetMapping/GetMappingApiTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ internal class TestVisitor : IMappingVisitor
229229

230230
public void Visit(IConstantKeywordProperty property) => Increment("constant_keyword");
231231

232+
public void Visit(IVersionProperty property) => Increment("version");
233+
232234
private void Increment(string key)
233235
{
234236
if (!Counts.ContainsKey(key)) Counts.Add(key, 0);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Nest;
6+
7+
namespace Tests.Mapping.Types.Specialized.Version
8+
{
9+
public class VersionTest
10+
{
11+
[Version]
12+
public string VersionNumber { get; set; }
13+
}
14+
15+
public class VersionAttributeTests : AttributeTestsBase<VersionTest>
16+
{
17+
protected override object ExpectJson => new
18+
{
19+
properties = new
20+
{
21+
versionNumber = new
22+
{
23+
type = "version"
24+
}
25+
}
26+
};
27+
}
28+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System;
6+
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
7+
using Nest;
8+
using Tests.Core.ManagedElasticsearch.Clusters;
9+
using Tests.Domain;
10+
using Tests.Framework.EndpointTests.TestState;
11+
12+
namespace Tests.Mapping.Types.Specialized.Version
13+
{
14+
[SkipVersion("<7.10.0", "Version property introduced in 7.10.0")]
15+
public class VersionPropertyTests : PropertyTestsBase
16+
{
17+
public VersionPropertyTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
18+
19+
protected override object ExpectJson => new
20+
{
21+
properties = new
22+
{
23+
name = new
24+
{
25+
type = "version"
26+
}
27+
}
28+
};
29+
30+
protected override Func<PropertiesDescriptor<Project>, IPromise<IProperties>> FluentProperties => f => f
31+
.Version(s => s
32+
.Name(p => p.Name)
33+
);
34+
35+
protected override IProperties InitializerProperties => new Properties
36+
{
37+
{
38+
"name", new VersionProperty
39+
{
40+
}
41+
}
42+
};
43+
}
44+
}

0 commit comments

Comments
 (0)