Skip to content

Commit 1fdec23

Browse files
Implement ml.estimate_model_memory.json (#4530) (#4603)
Implement ml.estimate_model_memory.json Co-authored-by: Stuart Cam <stuart.cam@elastic.co>
1 parent 7be50d1 commit 1fdec23

File tree

8 files changed

+302
-1
lines changed

8 files changed

+302
-1
lines changed

src/ApiGenerator/Configuration/CodeConfiguration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public static class CodeConfiguration
6666
"cluster.delete_component_template.json",
6767
"cluster.get_component_template.json",
6868
"cluster.put_component_template.json",
69-
"ml.estimate_model_memory.json",
7069
"ml.set_upgrade_mode.json",
7170
"security.get_builtin_privileges.json",
7271
"transform.delete_transform.json",

src/Nest/Descriptors.MachineLearning.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ protected DeleteModelSnapshotDescriptor(): base()
251251
// Request parameters
252252
}
253253

254+
///<summary>Descriptor for EstimateModelMemory</summary>
255+
public partial class EstimateModelMemoryDescriptor<TDocument> : RequestDescriptorBase<EstimateModelMemoryDescriptor<TDocument>, EstimateModelMemoryRequestParameters, IEstimateModelMemoryRequest>, IEstimateModelMemoryRequest
256+
{
257+
internal override ApiUrls ApiUrls => ApiUrlsLookups.MachineLearningEstimateModelMemory;
258+
// values part of the url path
259+
// Request parameters
260+
}
261+
254262
///<summary>Descriptor for FlushJob <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-flush-job.html</para></summary>
255263
public partial class FlushJobDescriptor : RequestDescriptorBase<FlushJobDescriptor, FlushJobRequestParameters, IFlushJobRequest>, IFlushJobRequest
256264
{

src/Nest/ElasticClient.MachineLearning.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,32 @@ internal MachineLearningNamespace(ElasticClient client): base(client)
277277
/// </summary>
278278
public Task<DeleteModelSnapshotResponse> DeleteModelSnapshotAsync(IDeleteModelSnapshotRequest request, CancellationToken ct = default) => DoRequestAsync<IDeleteModelSnapshotRequest, DeleteModelSnapshotResponse>(request, request.RequestParameters, ct);
279279
/// <summary>
280+
/// <c>POST</c> request to the <c>ml.estimate_model_memory</c> API, read more about this API online:
281+
/// <para></para>
282+
/// <a></a>
283+
/// </summary>
284+
public EstimateModelMemoryResponse EstimateModelMemory<TDocument>(Func<EstimateModelMemoryDescriptor<TDocument>, IEstimateModelMemoryRequest> selector)
285+
where TDocument : class => EstimateModelMemory(selector.InvokeOrDefault(new EstimateModelMemoryDescriptor<TDocument>()));
286+
/// <summary>
287+
/// <c>POST</c> request to the <c>ml.estimate_model_memory</c> API, read more about this API online:
288+
/// <para></para>
289+
/// <a></a>
290+
/// </summary>
291+
public Task<EstimateModelMemoryResponse> EstimateModelMemoryAsync<TDocument>(Func<EstimateModelMemoryDescriptor<TDocument>, IEstimateModelMemoryRequest> selector, CancellationToken ct = default)
292+
where TDocument : class => EstimateModelMemoryAsync(selector.InvokeOrDefault(new EstimateModelMemoryDescriptor<TDocument>()), ct);
293+
/// <summary>
294+
/// <c>POST</c> request to the <c>ml.estimate_model_memory</c> API, read more about this API online:
295+
/// <para></para>
296+
/// <a></a>
297+
/// </summary>
298+
public EstimateModelMemoryResponse EstimateModelMemory(IEstimateModelMemoryRequest request) => DoRequest<IEstimateModelMemoryRequest, EstimateModelMemoryResponse>(request, request.RequestParameters);
299+
/// <summary>
300+
/// <c>POST</c> request to the <c>ml.estimate_model_memory</c> API, read more about this API online:
301+
/// <para></para>
302+
/// <a></a>
303+
/// </summary>
304+
public Task<EstimateModelMemoryResponse> EstimateModelMemoryAsync(IEstimateModelMemoryRequest request, CancellationToken ct = default) => DoRequestAsync<IEstimateModelMemoryRequest, EstimateModelMemoryResponse>(request, request.RequestParameters, ct);
305+
/// <summary>
280306
/// <c>POST</c> request to the <c>ml.flush_job</c> API, read more about this API online:
281307
/// <para></para>
282308
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-flush-job.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ml-flush-job.html</a>

src/Nest/Requests.MachineLearning.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,20 @@ protected DeleteModelSnapshotRequest(): base()
430430
// Request parameters
431431
}
432432

433+
[InterfaceDataContract]
434+
public partial interface IEstimateModelMemoryRequest : IRequest<EstimateModelMemoryRequestParameters>
435+
{
436+
}
437+
438+
///<summary>Request for EstimateModelMemory</summary>
439+
public partial class EstimateModelMemoryRequest : PlainRequestBase<EstimateModelMemoryRequestParameters>, IEstimateModelMemoryRequest
440+
{
441+
protected IEstimateModelMemoryRequest Self => this;
442+
internal override ApiUrls ApiUrls => ApiUrlsLookups.MachineLearningEstimateModelMemory;
443+
// values part of the url path
444+
// Request parameters
445+
}
446+
433447
[InterfaceDataContract]
434448
public partial interface IFlushJobRequest : IRequest<FlushJobRequestParameters>
435449
{
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq.Expressions;
4+
using System.Runtime.Serialization;
5+
using Elasticsearch.Net.Utf8Json;
6+
7+
namespace Nest
8+
{
9+
[MapsApi("ml.estimate_model_memory.json")]
10+
[ReadAs(typeof(EstimateModelMemoryRequest))]
11+
public partial interface IEstimateModelMemoryRequest
12+
{
13+
/// <summary>
14+
/// For a list of the properties that you can specify in the analysis_config component of the body
15+
/// of this API, see analysis_config.
16+
/// </summary>
17+
[DataMember(Name ="analysis_config")]
18+
IAnalysisConfig AnalysisConfig { get; set; }
19+
20+
/// <summary>
21+
/// Estimates of the cardinality that will be observed for fields over the whole time period that
22+
/// the job analyzes data. To produce a good answer, values must be provided for fields referenced
23+
/// in the by_field_name, over_field_name and partition_field_name of any detectors. It does not matter
24+
/// if values are provided for other fields. If no detectors have a by_field_name, over_field_name or
25+
/// partition_field_name then overall_cardinality can be omitted from the request.
26+
/// </summary>
27+
[DataMember(Name = "overall_cardinality")]
28+
IOverallCardinality OverallCardinality { get; set; }
29+
30+
/// <summary>
31+
/// Estimates of the highest cardinality in a single bucket that will be observed for influencer
32+
/// fields over the time period that the job analyzes data. To produce a good answer, values must
33+
/// be provided for all influencer fields. It does not matter if values are provided for fields
34+
/// that are not listed as influencers. If there are no influencers then max_bucket_cardinality
35+
/// can be omitted from the request.
36+
/// </summary>
37+
[DataMember(Name = "max_bucket_cardinality")]
38+
IMaxBucketCardinality MaxBucketCardinality { get; set; }
39+
}
40+
41+
public partial class EstimateModelMemoryRequest
42+
{
43+
/// <inheritdoc />
44+
public IAnalysisConfig AnalysisConfig { get; set; }
45+
46+
/// <inheritdoc />
47+
public IOverallCardinality OverallCardinality { get; set; }
48+
49+
/// <inheritdoc />
50+
public IMaxBucketCardinality MaxBucketCardinality { get; set; }
51+
}
52+
53+
public partial class EstimateModelMemoryDescriptor<TDocument> where TDocument : class
54+
{
55+
IAnalysisConfig IEstimateModelMemoryRequest.AnalysisConfig { get; set; }
56+
IOverallCardinality IEstimateModelMemoryRequest.OverallCardinality { get; set; }
57+
IMaxBucketCardinality IEstimateModelMemoryRequest.MaxBucketCardinality { get; set; }
58+
59+
/// <inheritdoc />
60+
public EstimateModelMemoryDescriptor<TDocument> AnalysisConfig(Func<AnalysisConfigDescriptor<TDocument>, IAnalysisConfig> selector) =>
61+
Assign(selector, (a, v) => a.AnalysisConfig = v?.Invoke(new AnalysisConfigDescriptor<TDocument>()));
62+
63+
/// <inheritdoc />
64+
public EstimateModelMemoryDescriptor<TDocument> OverallCardinality(Func<OverallCardinalityDescriptor<TDocument>, IPromise<IOverallCardinality>> analyzerSelector) =>
65+
Assign(analyzerSelector, (a, v) => a.OverallCardinality = v?.Invoke(new OverallCardinalityDescriptor<TDocument>())?.Value);
66+
67+
/// <inheritdoc />
68+
public EstimateModelMemoryDescriptor<TDocument> MaxBucketCardinality(Func<MaxBucketCardinalityDescriptor<TDocument>, IPromise<IMaxBucketCardinality>> analyzerSelector) =>
69+
Assign(analyzerSelector, (a, v) => a.MaxBucketCardinality = v?.Invoke(new MaxBucketCardinalityDescriptor<TDocument>())?.Value);
70+
}
71+
72+
[JsonFormatter(typeof(VerbatimDictionaryKeysFormatter<OverallCardinality, IOverallCardinality, Field, long>))]
73+
public interface IOverallCardinality : IIsADictionary<Field, long> { }
74+
75+
public class OverallCardinality : IsADictionaryBase<Field, long>, IOverallCardinality
76+
{
77+
public OverallCardinality() { }
78+
79+
public OverallCardinality(IDictionary<Field, long> container) : base(container) { }
80+
81+
public void Add(Field field, long cardinality) => BackingDictionary.Add(field, cardinality);
82+
}
83+
84+
public class OverallCardinality<T> : OverallCardinality where T : class
85+
{
86+
public void Add<TValue>(Expression<Func<T, TValue>> field, long cardinality) => BackingDictionary.Add(field, cardinality);
87+
}
88+
89+
public class OverallCardinalityDescriptor<T> : IsADictionaryDescriptorBase<OverallCardinalityDescriptor<T>, IOverallCardinality, Field, long> where T : class
90+
{
91+
public OverallCardinalityDescriptor() : base(new OverallCardinality()) { }
92+
93+
public OverallCardinalityDescriptor<T> Field(Field field, long cardinality) => Assign(field, cardinality);
94+
95+
public OverallCardinalityDescriptor<T> Field<TValue>(Expression<Func<T, TValue>> field, long cardinality) => Assign(field, cardinality);
96+
}
97+
98+
[JsonFormatter(typeof(VerbatimDictionaryKeysFormatter<MaxBucketCardinality, IMaxBucketCardinality, Field, long>))]
99+
public interface IMaxBucketCardinality : IIsADictionary<Field, long> { }
100+
101+
public class MaxBucketCardinality : IsADictionaryBase<Field, long>, IMaxBucketCardinality
102+
{
103+
public MaxBucketCardinality() { }
104+
105+
public MaxBucketCardinality(IDictionary<Field, long> container) : base(container) { }
106+
107+
public MaxBucketCardinality(Dictionary<Field, long> container) : base(container) { }
108+
109+
public void Add(Field field, long cardinality) => BackingDictionary.Add(field, cardinality);
110+
}
111+
112+
public class MaxBucketCardinality<T> : MaxBucketCardinality where T : class
113+
{
114+
public void Add<TValue>(Expression<Func<T, TValue>> field, long cardinality) => BackingDictionary.Add(field, cardinality);
115+
}
116+
117+
public class MaxBucketCardinalityDescriptor<T> : IsADictionaryDescriptorBase<MaxBucketCardinalityDescriptor<T>, IMaxBucketCardinality, Field, long> where T : class
118+
{
119+
public MaxBucketCardinalityDescriptor() : base(new MaxBucketCardinality()) { }
120+
121+
public MaxBucketCardinalityDescriptor<T> Field(Field field, long cardinality) => Assign(field, cardinality);
122+
123+
public MaxBucketCardinalityDescriptor<T> Field<TValue>(Expression<Func<T, TValue>> field, long cardinality) => Assign(field, cardinality);
124+
}
125+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace Nest
4+
{
5+
public class EstimateModelMemoryResponse : ResponseBase
6+
{
7+
[DataMember(Name ="model_memory_estimate")]
8+
public string ModelMemoryEstimate { get; internal set; }
9+
}
10+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using Elastic.Xunit.XunitPlumbing;
3+
using Elasticsearch.Net;
4+
using Nest;
5+
using Tests.Core.Extensions;
6+
using Tests.Domain;
7+
using Tests.Framework.EndpointTests.TestState;
8+
using static Nest.Infer;
9+
10+
namespace Tests.XPack.MachineLearning.EstimateModelMemory
11+
{
12+
[SkipVersion("<7.7.0", "Introduced in 7.7.0")]
13+
public class EstimateModelMemoryApiTests : MachineLearningIntegrationTestBase<EstimateModelMemoryResponse, IEstimateModelMemoryRequest, EstimateModelMemoryDescriptor<Metric>, EstimateModelMemoryRequest>
14+
{
15+
public EstimateModelMemoryApiTests(MachineLearningCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
16+
17+
protected override bool ExpectIsValid => true;
18+
protected override int ExpectStatusCode => 200;
19+
protected override Func<EstimateModelMemoryDescriptor<Metric>, IEstimateModelMemoryRequest> Fluent => f => f
20+
.AnalysisConfig(a => a
21+
.BucketSpan("30m")
22+
.Latency("0s")
23+
.Detectors(d => d.Sum(c => c.FieldName(r => r.Total)))
24+
)
25+
.OverallCardinality(m =>
26+
m.Field(f => f.Response, 50)
27+
.Field(f => f.Accept, 10)
28+
)
29+
.MaxBucketCardinality(m =>
30+
m.Field(f => f.Response, 500)
31+
.Field(f => f.Accept, 100)
32+
);
33+
34+
protected override HttpMethod HttpMethod => HttpMethod.POST;
35+
36+
protected override object ExpectJson => new
37+
{
38+
analysis_config = new
39+
{
40+
bucket_span = "30m",
41+
detectors = new[]
42+
{
43+
new
44+
{
45+
function = "sum",
46+
field_name = "total"
47+
}
48+
},
49+
latency = "0s",
50+
},
51+
overall_cardinality = new
52+
{
53+
response = 50,
54+
accept = 10,
55+
},
56+
max_bucket_cardinality = new
57+
{
58+
response = 500,
59+
accept = 100,
60+
}
61+
};
62+
63+
protected override EstimateModelMemoryRequest Initializer => new EstimateModelMemoryRequest
64+
{
65+
AnalysisConfig = new AnalysisConfig
66+
{
67+
BucketSpan = "30m",
68+
Latency = "0s",
69+
Detectors = new[]
70+
{
71+
new SumDetector
72+
{
73+
FieldName = Field<Metric>(f => f.Total)
74+
}
75+
}
76+
},
77+
OverallCardinality = new OverallCardinality
78+
{
79+
{ Field<Metric>(f => f.Response), 50 },
80+
{ Field<Metric>(f => f.Accept), 10 }
81+
},
82+
MaxBucketCardinality = new MaxBucketCardinality
83+
{
84+
{ Field<Metric>(f => f.Response), 500 },
85+
{ Field<Metric>(f => f.Accept), 100 }
86+
}
87+
};
88+
89+
protected override string UrlPath => $"/_ml/anomaly_detectors/_estimate_model_memory";
90+
91+
protected override LazyResponses ClientUsage() => Calls(
92+
(client, f) => client.MachineLearning.EstimateModelMemory(f),
93+
(client, f) => client.MachineLearning.EstimateModelMemoryAsync(f),
94+
(client, r) => client.MachineLearning.EstimateModelMemory(r),
95+
(client, r) => client.MachineLearning.EstimateModelMemoryAsync(r)
96+
);
97+
98+
protected override EstimateModelMemoryDescriptor<Metric> NewDescriptor() => new EstimateModelMemoryDescriptor<Metric>();
99+
100+
protected override void ExpectResponse(EstimateModelMemoryResponse response) => response.ShouldBeValid();
101+
}
102+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Threading.Tasks;
2+
using Elastic.Xunit.XunitPlumbing;
3+
using Nest;
4+
using Tests.Framework.EndpointTests;
5+
using static Tests.Framework.EndpointTests.UrlTester;
6+
7+
namespace Tests.XPack.MachineLearning.EstimateModelMemory
8+
{
9+
public class EstimateModelMemoryUrlTests : UrlTestsBase
10+
{
11+
[U] public override async Task Urls() => await POST("/_ml/anomaly_detectors/_estimate_model_memory")
12+
.Fluent(c => c.MachineLearning.EstimateModelMemory(new EstimateModelMemoryRequest()))
13+
.Request(c => c.MachineLearning.EstimateModelMemory(new EstimateModelMemoryRequest()))
14+
.FluentAsync(c => c.MachineLearning.EstimateModelMemoryAsync(new EstimateModelMemoryRequest()))
15+
.RequestAsync(c => c.MachineLearning.EstimateModelMemoryAsync(new EstimateModelMemoryRequest()));
16+
}
17+
}

0 commit comments

Comments
 (0)