Skip to content

Commit 7919120

Browse files
authored
[Backport master] Support for calculated numeric fields (#5626)
* Update RuntimeField to use IInlineScript (#5546) (cherry picked from commit 8d04047) * Support for calculated numeric fields (#5622) (cherry picked from commit b29f03d) * Remove boost
1 parent eaf380a commit 7919120

File tree

4 files changed

+121
-3
lines changed

4 files changed

+121
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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.Runtime.Serialization;
6+
using Elasticsearch.Net;
7+
8+
namespace Nest
9+
{
10+
[StringEnum]
11+
public enum OnScriptError
12+
{
13+
[EnumMember(Value = "fail")]
14+
Fail,
15+
[EnumMember(Value = "continue")]
16+
Continue
17+
}
18+
}

src/Nest/Mapping/Types/Core/Number/NumberAttribute.cs

+15-1
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,27 @@ public double ScalingFactor
4444
set => Self.ScalingFactor = value;
4545
}
4646

47+
public IInlineScript Script
48+
{
49+
get => Self.Script;
50+
set => Self.Script = value;
51+
}
52+
53+
public OnScriptError OnScriptError
54+
{
55+
get => Self.OnScriptError.GetValueOrDefault();
56+
set => Self.OnScriptError = value;
57+
}
58+
4759
bool? INumberProperty.Coerce { get; set; }
4860
INumericFielddata INumberProperty.Fielddata { get; set; }
4961
bool? INumberProperty.IgnoreMalformed { get; set; }
50-
5162
bool? INumberProperty.Index { get; set; }
5263
double? INumberProperty.NullValue { get; set; }
5364
double? INumberProperty.ScalingFactor { get; set; }
65+
IInlineScript INumberProperty.Script { get; set; }
66+
OnScriptError? INumberProperty.OnScriptError { get; set; }
67+
5468
private INumberProperty Self => this;
5569
}
5670
}

src/Nest/Mapping/Types/Core/Number/NumberProperty.cs

+36-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ public interface INumberProperty : IDocValuesProperty
3333

3434
[DataMember(Name = "scaling_factor")]
3535
double? ScalingFactor { get; set; }
36+
37+
/// <summary>
38+
/// If this parameter is set, then the field will index values generated by this script, rather than reading the values directly from the source.
39+
/// If a value is set for this field on the input document, then the document will be rejected with an error.
40+
/// Scripts are in the same format as their runtime equivalent. Scripts can only be configured on long and double field types.
41+
/// </summary>
42+
[DataMember(Name = "script")]
43+
IInlineScript Script { get; set; }
44+
45+
/// <summary>
46+
/// Defines what to do if the script defined by the `script` parameter throws an error at indexing time.Accepts `reject` (default), which
47+
/// will cause the entire document to be rejected, and `ignore`, which will register the field in the document's ignored metadata field and
48+
/// continue indexing.This parameter can only be set if the `script` field is also set.
49+
/// </summary>
50+
[DataMember(Name = "on_script_error")]
51+
OnScriptError? OnScriptError { get; set; }
3652
}
3753

3854
[DebuggerDisplay("{DebugDisplay}")]
@@ -45,10 +61,15 @@ public NumberProperty(NumberType type) : base(type.ToFieldType()) { }
4561
public bool? Coerce { get; set; }
4662
public INumericFielddata Fielddata { get; set; }
4763
public bool? IgnoreMalformed { get; set; }
48-
4964
public bool? Index { get; set; }
5065
public double? NullValue { get; set; }
5166
public double? ScalingFactor { get; set; }
67+
68+
/// <inheritdoc />
69+
public IInlineScript Script { get; set; }
70+
71+
/// <inheritdoc />
72+
public OnScriptError? OnScriptError { get; set; }
5273
}
5374

5475
[DebuggerDisplay("{DebugDisplay}")]
@@ -65,10 +86,11 @@ protected NumberPropertyDescriptorBase(FieldType type) : base(type) { }
6586
bool? INumberProperty.Coerce { get; set; }
6687
INumericFielddata INumberProperty.Fielddata { get; set; }
6788
bool? INumberProperty.IgnoreMalformed { get; set; }
68-
6989
bool? INumberProperty.Index { get; set; }
7090
double? INumberProperty.NullValue { get; set; }
7191
double? INumberProperty.ScalingFactor { get; set; }
92+
IInlineScript INumberProperty.Script { get; set; }
93+
OnScriptError? INumberProperty.OnScriptError { get; set; }
7294

7395
public TDescriptor Type(NumberType? type) => Assign(type?.GetStringValue(), (a, v) => a.Type = v);
7496

@@ -85,6 +107,18 @@ public TDescriptor Fielddata(Func<NumericFielddataDescriptor, INumericFielddata>
85107
Assign(selector(new NumericFielddataDescriptor()), (a, v) => a.Fielddata = v);
86108

87109
public TDescriptor ScalingFactor(double? scalingFactor) => Assign(scalingFactor, (a, v) => a.ScalingFactor = v);
110+
111+
/// <inheritdoc cref="INumberProperty.Script" />
112+
public TDescriptor Script(IInlineScript inlineScript) => Assign(inlineScript, (a, v) => a.Script = v);
113+
114+
/// <inheritdoc cref="INumberProperty.Script" />
115+
public TDescriptor Script(string source) => Assign(source, (a, v) => a.Script = new InlineScript(source));
116+
117+
/// <inheritdoc cref="INumberProperty.Script" />
118+
public TDescriptor Script(Func<InlineScriptDescriptor, IInlineScript> selector) => Assign(selector, (a, v) => a.Script = v?.Invoke(new InlineScriptDescriptor()));
119+
120+
/// <inheritdoc cref="INumberProperty.OnScriptError" />
121+
public TDescriptor OnScriptError(OnScriptError? onScriptError) => Assign(onScriptError, (a, v) => a.OnScriptError = v);
88122
}
89123

90124
public class NumberPropertyDescriptor<T> : NumberPropertyDescriptorBase<NumberPropertyDescriptor<T>, INumberProperty, T>

tests/Tests/Mapping/Types/Core/Number/NumberPropertyTests.cs

+52
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information
44

55
using System;
6+
using System.Collections.Generic;
67
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
78
using Nest;
89
using Tests.Core.ManagedElasticsearch.Clusters;
@@ -157,4 +158,55 @@ public UnsignedLongNumberPropertyTests(WritableCluster cluster, EndpointUsage us
157158
}
158159
};
159160
}
161+
162+
[SkipVersion("<7.13.0", "Script support added in 7.13.0")]
163+
public class ScriptedNumberPropertyTests : PropertyTestsBase
164+
{
165+
public ScriptedNumberPropertyTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
166+
167+
protected override object ExpectJson => new
168+
{
169+
properties = new
170+
{
171+
doublesCommits = new
172+
{
173+
type = "long",
174+
script = new
175+
{
176+
source = "emit((long)(doc['numberOfCommits'].value * params.multiplier))",
177+
@params = new Dictionary<string, int>
178+
{
179+
{"multiplier", 2 }
180+
}
181+
},
182+
on_script_error = "continue"
183+
}
184+
}
185+
};
186+
187+
protected override Func<PropertiesDescriptor<Project>, IPromise<IProperties>> FluentProperties => f => f
188+
.Number(n => n
189+
.Name("doublesCommits")
190+
.Type(NumberType.Long)
191+
.Script(s => s.Source("emit((long)(doc['numberOfCommits'].value * params.multiplier))").Params(p => p.Add("multiplier", 2)))
192+
.OnScriptError(OnScriptError.Continue)
193+
);
194+
195+
protected override IProperties InitializerProperties => new Properties
196+
{
197+
{
198+
"doublesCommits", new NumberProperty(NumberType.Long)
199+
{
200+
Script = new InlineScript("emit((long)(doc['numberOfCommits'].value * params.multiplier))")
201+
{
202+
Params = new Dictionary<string, object>
203+
{
204+
{ "multiplier", 2 }
205+
}
206+
},
207+
OnScriptError = OnScriptError.Continue
208+
}
209+
}
210+
};
211+
}
160212
}

0 commit comments

Comments
 (0)