Skip to content

Commit ff9a9a6

Browse files
Add support for MSearch (#6445) (#6446)
* Generate types for msearch * Add stub of test class * Completed POC ready for code gen * Code-gen for array bodied requests * Updating to latest specification changes Co-authored-by: Steve Gordon <sgordon@hotmail.co.uk>
1 parent e38213e commit ff9a9a6

21 files changed

+2780
-84
lines changed

build/scripts/scripts.fsproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<OutputType>Exe</OutputType>
55
<!-- Type Providers are restored using net461, fine for netcoreapp2.2 so we kill the warning -->
66
<NoWarn>$(NoWarn);NU1701</NoWarn>
7+
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
78
</PropertyGroup>
89
<ItemGroup>
910
<Compile Include="Commandline.fs" />
@@ -34,17 +35,15 @@
3435
<Content Include="..\..\.github\workflows\make-release-notes.yml"><Link>make-release-notes.yml</Link></Content>
3536
</ItemGroup>
3637
<ItemGroup>
38+
<PackageReference Include="FSharp.Core" Version="6.0.4" /> <!-- Hardcoded for manual control over the version, otherwise this updates when the SDK updates. -->
3739
<PackageReference Include="Bullseye" Version="3.3.0" />
3840
<PackageReference Include="Elastic.Elasticsearch.Managed" Version="0.3.0" />
39-
4041
<PackageReference Include="Fake.Core.Environment" Version="5.15.0" />
4142
<PackageReference Include="Fake.Core.SemVer" Version="5.15.0" />
4243
<PackageReference Include="Fake.IO.FileSystem" Version="5.15.0" />
4344
<PackageReference Include="Fake.IO.Zip" Version="5.15.0" />
4445
<PackageReference Include="Fake.Tools.Git" Version="5.15.0" />
45-
4646
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
47-
4847
<PackageReference Include="Octokit" Version="0.32.0" />
4948
<PackageReference Include="Proc" Version="0.6.1" />
5049
</ItemGroup>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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.Collections.Generic;
6+
using System.IO;
7+
using System.Linq;
8+
using System.Text.Json;
9+
using System.Text.Json.Serialization;
10+
using System.Threading.Tasks;
11+
using Elastic.Transport;
12+
13+
namespace Elastic.Clients.Elasticsearch
14+
{
15+
public sealed partial class MultiSearchRequestDescriptor<TDocument>
16+
{
17+
internal override void BeforeRequest() => TypedKeys(true);
18+
}
19+
20+
public sealed partial class MultiSearchRequestDescriptor
21+
{
22+
internal override void BeforeRequest() => TypedKeys(true);
23+
}
24+
25+
public partial class MultiSearchRequest
26+
{
27+
internal override void BeforeRequest() => TypedKeys = true;
28+
}
29+
30+
// POC - If we have more than one union doing this, can we autogenerate with correct ctors etc.
31+
public class SearchRequestItem : IStreamSerializable
32+
{
33+
public SearchRequestItem(MultisearchBody body) => Body = body;
34+
35+
public SearchRequestItem(MultisearchHeader header, MultisearchBody body)
36+
{
37+
Header = header;
38+
Body = body;
39+
}
40+
41+
public MultisearchHeader Header { get; init; }
42+
public MultisearchBody Body { get; init; }
43+
44+
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
45+
{
46+
if (Body is null)
47+
return;
48+
49+
if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
50+
{
51+
JsonSerializer.Serialize(stream, Header, options);
52+
stream.WriteByte((byte)'\n');
53+
JsonSerializer.Serialize(stream, Body, options);
54+
stream.WriteByte((byte)'\n');
55+
}
56+
}
57+
58+
async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
59+
{
60+
if (Body is null)
61+
return;
62+
63+
if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
64+
{
65+
await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false);
66+
stream.WriteByte((byte)'\n');
67+
await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false);
68+
stream.WriteByte((byte)'\n');
69+
}
70+
}
71+
}
72+
73+
public partial class ResponseBody<TDocument>
74+
{
75+
[JsonIgnore]
76+
public IReadOnlyCollection<Hit<TDocument>> Hits => HitsMetadata.Hits;
77+
78+
[JsonIgnore]
79+
public IReadOnlyCollection<TDocument> Documents => HitsMetadata.Hits.Select(s => s.Source).ToReadOnlyCollection();
80+
81+
[JsonIgnore]
82+
public long Total => HitsMetadata?.Total?.Value ?? -1;
83+
}
84+
85+
public partial class MultiSearchResponse<TDocument>
86+
{
87+
public override bool IsValid => base.IsValid && (Responses?.All(b => b.Item1 is not null && b.Item1.Status == 200) ?? true);
88+
89+
[JsonIgnore]
90+
public int TotalResponses => Responses.HasAny() ? Responses.Count() : 0;
91+
}
92+
}

src/Elastic.Clients.Elasticsearch/_Generated/Api/ApiUrlsLookup.g.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ internal static class ApiUrlsLookups
216216
internal static ApiUrls MachineLearningValidateDetector = new ApiUrls(new[] { "/_ml/anomaly_detectors/_validate/detector" });
217217
internal static ApiUrls MachineLearningValidate = new ApiUrls(new[] { "/_ml/anomaly_detectors/_validate" });
218218
internal static ApiUrls NoNamespaceMget = new ApiUrls(new[] { "/_mget", "/{index}/_mget" });
219+
internal static ApiUrls NoNamespaceMsearch = new ApiUrls(new[] { "/_msearch", "/{index}/_msearch" });
219220
internal static ApiUrls NodesHotThreads = new ApiUrls(new[] { "/_nodes/hot_threads", "/_nodes/{node_id}/hot_threads" });
220221
internal static ApiUrls NodesInfo = new ApiUrls(new[] { "/_nodes", "/_nodes/{node_id}", "/_nodes/{metric}", "/_nodes/{node_id}/{metric}" });
221222
internal static ApiUrls NodesReloadSecureSettings = new ApiUrls(new[] { "/_nodes/reload_secure_settings", "/_nodes/{node_id}/reload_secure_settings" });
Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
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+
// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
6+
// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
7+
// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗
8+
// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝
9+
// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗
10+
// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
11+
// ------------------------------------------------
12+
//
13+
// This file is automatically generated.
14+
// Please do not edit these files manually.
15+
//
16+
// ------------------------------------------------
17+
18+
using Elastic.Transport;
19+
using System;
20+
using System.Collections.Generic;
21+
using System.IO;
22+
using System.Linq.Expressions;
23+
using System.Text.Json;
24+
using System.Text.Json.Serialization;
25+
using System.Threading.Tasks;
26+
27+
#nullable restore
28+
namespace Elastic.Clients.Elasticsearch
29+
{
30+
public sealed class MultiSearchRequestParameters : RequestParameters<MultiSearchRequestParameters>
31+
{
32+
[JsonIgnore]
33+
public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }
34+
35+
[JsonIgnore]
36+
public bool? CcsMinimizeRoundtrips { get => Q<bool?>("ccs_minimize_roundtrips"); set => Q("ccs_minimize_roundtrips", value); }
37+
38+
[JsonIgnore]
39+
public Elastic.Clients.Elasticsearch.ExpandWildcards? ExpandWildcards { get => Q<Elastic.Clients.Elasticsearch.ExpandWildcards?>("expand_wildcards"); set => Q("expand_wildcards", value); }
40+
41+
[JsonIgnore]
42+
public bool? IgnoreThrottled { get => Q<bool?>("ignore_throttled"); set => Q("ignore_throttled", value); }
43+
44+
[JsonIgnore]
45+
public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }
46+
47+
[JsonIgnore]
48+
public long? MaxConcurrentSearches { get => Q<long?>("max_concurrent_searches"); set => Q("max_concurrent_searches", value); }
49+
50+
[JsonIgnore]
51+
public long? MaxConcurrentShardRequests { get => Q<long?>("max_concurrent_shard_requests"); set => Q("max_concurrent_shard_requests", value); }
52+
53+
[JsonIgnore]
54+
public long? PreFilterShardSize { get => Q<long?>("pre_filter_shard_size"); set => Q("pre_filter_shard_size", value); }
55+
56+
[JsonIgnore]
57+
public bool? RestTotalHitsAsInt { get => Q<bool?>("rest_total_hits_as_int"); set => Q("rest_total_hits_as_int", value); }
58+
59+
[JsonIgnore]
60+
public Elastic.Clients.Elasticsearch.Routing? Routing { get => Q<Elastic.Clients.Elasticsearch.Routing?>("routing"); set => Q("routing", value); }
61+
62+
[JsonIgnore]
63+
public Elastic.Clients.Elasticsearch.SearchType? SearchType { get => Q<Elastic.Clients.Elasticsearch.SearchType?>("search_type"); set => Q("search_type", value); }
64+
65+
[JsonIgnore]
66+
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }
67+
}
68+
69+
public partial class MultiSearchRequest : PlainRequestBase<MultiSearchRequestParameters>, IStreamSerializable
70+
{
71+
public MultiSearchRequest()
72+
{
73+
}
74+
75+
public MultiSearchRequest(Elastic.Clients.Elasticsearch.Indices? indices) : base(r => r.Optional("index", indices))
76+
{
77+
}
78+
79+
internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
80+
protected override HttpMethod HttpMethod => HttpMethod.POST;
81+
protected override bool SupportsBody => true;
82+
[JsonIgnore]
83+
public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }
84+
85+
[JsonIgnore]
86+
public bool? CcsMinimizeRoundtrips { get => Q<bool?>("ccs_minimize_roundtrips"); set => Q("ccs_minimize_roundtrips", value); }
87+
88+
[JsonIgnore]
89+
public Elastic.Clients.Elasticsearch.ExpandWildcards? ExpandWildcards { get => Q<Elastic.Clients.Elasticsearch.ExpandWildcards?>("expand_wildcards"); set => Q("expand_wildcards", value); }
90+
91+
[JsonIgnore]
92+
public bool? IgnoreThrottled { get => Q<bool?>("ignore_throttled"); set => Q("ignore_throttled", value); }
93+
94+
[JsonIgnore]
95+
public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }
96+
97+
[JsonIgnore]
98+
public long? MaxConcurrentSearches { get => Q<long?>("max_concurrent_searches"); set => Q("max_concurrent_searches", value); }
99+
100+
[JsonIgnore]
101+
public long? MaxConcurrentShardRequests { get => Q<long?>("max_concurrent_shard_requests"); set => Q("max_concurrent_shard_requests", value); }
102+
103+
[JsonIgnore]
104+
public long? PreFilterShardSize { get => Q<long?>("pre_filter_shard_size"); set => Q("pre_filter_shard_size", value); }
105+
106+
[JsonIgnore]
107+
public bool? RestTotalHitsAsInt { get => Q<bool?>("rest_total_hits_as_int"); set => Q("rest_total_hits_as_int", value); }
108+
109+
[JsonIgnore]
110+
public Elastic.Clients.Elasticsearch.Routing? Routing { get => Q<Elastic.Clients.Elasticsearch.Routing?>("routing"); set => Q("routing", value); }
111+
112+
[JsonIgnore]
113+
public Elastic.Clients.Elasticsearch.SearchType? SearchType { get => Q<Elastic.Clients.Elasticsearch.SearchType?>("search_type"); set => Q("search_type", value); }
114+
115+
[JsonIgnore]
116+
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }
117+
118+
public List<SearchRequestItem> Searches { get; set; }
119+
120+
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
121+
{
122+
if (Searches is null)
123+
return;
124+
foreach (var item in Searches)
125+
{
126+
if (item is IStreamSerializable serializable)
127+
serializable.Serialize(stream, settings, formatting);
128+
}
129+
}
130+
131+
async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
132+
{
133+
if (Searches is null)
134+
return;
135+
foreach (var item in Searches)
136+
{
137+
if (item is IStreamSerializable serializable)
138+
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
139+
}
140+
}
141+
}
142+
143+
public sealed partial class MultiSearchRequestDescriptor<TDocument> : RequestDescriptorBase<MultiSearchRequestDescriptor<TDocument>, MultiSearchRequestParameters>, IStreamSerializable
144+
{
145+
internal MultiSearchRequestDescriptor(Action<MultiSearchRequestDescriptor<TDocument>> configure) => configure.Invoke(this);
146+
public MultiSearchRequestDescriptor()
147+
{
148+
}
149+
150+
internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
151+
protected override HttpMethod HttpMethod => HttpMethod.POST;
152+
protected override bool SupportsBody => true;
153+
public MultiSearchRequestDescriptor<TDocument> AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
154+
public MultiSearchRequestDescriptor<TDocument> CcsMinimizeRoundtrips(bool? ccsMinimizeRoundtrips = true) => Qs("ccs_minimize_roundtrips", ccsMinimizeRoundtrips);
155+
public MultiSearchRequestDescriptor<TDocument> ExpandWildcards(Elastic.Clients.Elasticsearch.ExpandWildcards? expandWildcards) => Qs("expand_wildcards", expandWildcards);
156+
public MultiSearchRequestDescriptor<TDocument> IgnoreThrottled(bool? ignoreThrottled = true) => Qs("ignore_throttled", ignoreThrottled);
157+
public MultiSearchRequestDescriptor<TDocument> IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);
158+
public MultiSearchRequestDescriptor<TDocument> MaxConcurrentSearches(long? maxConcurrentSearches) => Qs("max_concurrent_searches", maxConcurrentSearches);
159+
public MultiSearchRequestDescriptor<TDocument> MaxConcurrentShardRequests(long? maxConcurrentShardRequests) => Qs("max_concurrent_shard_requests", maxConcurrentShardRequests);
160+
public MultiSearchRequestDescriptor<TDocument> PreFilterShardSize(long? preFilterShardSize) => Qs("pre_filter_shard_size", preFilterShardSize);
161+
public MultiSearchRequestDescriptor<TDocument> RestTotalHitsAsInt(bool? restTotalHitsAsInt = true) => Qs("rest_total_hits_as_int", restTotalHitsAsInt);
162+
public MultiSearchRequestDescriptor<TDocument> Routing(Elastic.Clients.Elasticsearch.Routing? routing) => Qs("routing", routing);
163+
public MultiSearchRequestDescriptor<TDocument> SearchType(Elastic.Clients.Elasticsearch.SearchType? searchType) => Qs("search_type", searchType);
164+
public MultiSearchRequestDescriptor<TDocument> TypedKeys(bool? typedKeys = true) => Qs("typed_keys", typedKeys);
165+
public MultiSearchRequestDescriptor<TDocument> Indices(Elastic.Clients.Elasticsearch.Indices? indices)
166+
{
167+
RouteValues.Optional("index", indices);
168+
return Self;
169+
}
170+
171+
protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
172+
{
173+
}
174+
175+
List<SearchRequestItem> _items = new();
176+
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
177+
{
178+
if (_items is null)
179+
return;
180+
foreach (var item in _items)
181+
{
182+
if (item is IStreamSerializable serializable)
183+
serializable.Serialize(stream, settings, formatting);
184+
}
185+
}
186+
187+
async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
188+
{
189+
if (_items is null)
190+
return;
191+
foreach (var item in _items)
192+
{
193+
if (item is IStreamSerializable serializable)
194+
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
195+
}
196+
}
197+
198+
public MultiSearchRequestDescriptor<TDocument> AddSearch(SearchRequestItem search)
199+
{
200+
_items.Add(search);
201+
return this;
202+
}
203+
}
204+
205+
public sealed partial class MultiSearchRequestDescriptor : RequestDescriptorBase<MultiSearchRequestDescriptor, MultiSearchRequestParameters>, IStreamSerializable
206+
{
207+
internal MultiSearchRequestDescriptor(Action<MultiSearchRequestDescriptor> configure) => configure.Invoke(this);
208+
public MultiSearchRequestDescriptor()
209+
{
210+
}
211+
212+
internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
213+
protected override HttpMethod HttpMethod => HttpMethod.POST;
214+
protected override bool SupportsBody => true;
215+
public MultiSearchRequestDescriptor AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
216+
public MultiSearchRequestDescriptor CcsMinimizeRoundtrips(bool? ccsMinimizeRoundtrips = true) => Qs("ccs_minimize_roundtrips", ccsMinimizeRoundtrips);
217+
public MultiSearchRequestDescriptor ExpandWildcards(Elastic.Clients.Elasticsearch.ExpandWildcards? expandWildcards) => Qs("expand_wildcards", expandWildcards);
218+
public MultiSearchRequestDescriptor IgnoreThrottled(bool? ignoreThrottled = true) => Qs("ignore_throttled", ignoreThrottled);
219+
public MultiSearchRequestDescriptor IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);
220+
public MultiSearchRequestDescriptor MaxConcurrentSearches(long? maxConcurrentSearches) => Qs("max_concurrent_searches", maxConcurrentSearches);
221+
public MultiSearchRequestDescriptor MaxConcurrentShardRequests(long? maxConcurrentShardRequests) => Qs("max_concurrent_shard_requests", maxConcurrentShardRequests);
222+
public MultiSearchRequestDescriptor PreFilterShardSize(long? preFilterShardSize) => Qs("pre_filter_shard_size", preFilterShardSize);
223+
public MultiSearchRequestDescriptor RestTotalHitsAsInt(bool? restTotalHitsAsInt = true) => Qs("rest_total_hits_as_int", restTotalHitsAsInt);
224+
public MultiSearchRequestDescriptor Routing(Elastic.Clients.Elasticsearch.Routing? routing) => Qs("routing", routing);
225+
public MultiSearchRequestDescriptor SearchType(Elastic.Clients.Elasticsearch.SearchType? searchType) => Qs("search_type", searchType);
226+
public MultiSearchRequestDescriptor TypedKeys(bool? typedKeys = true) => Qs("typed_keys", typedKeys);
227+
public MultiSearchRequestDescriptor Indices(Elastic.Clients.Elasticsearch.Indices? indices)
228+
{
229+
RouteValues.Optional("index", indices);
230+
return Self;
231+
}
232+
233+
protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
234+
{
235+
}
236+
237+
List<SearchRequestItem> _items = new();
238+
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
239+
{
240+
if (_items is null)
241+
return;
242+
foreach (var item in _items)
243+
{
244+
if (item is IStreamSerializable serializable)
245+
serializable.Serialize(stream, settings, formatting);
246+
}
247+
}
248+
249+
async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
250+
{
251+
if (_items is null)
252+
return;
253+
foreach (var item in _items)
254+
{
255+
if (item is IStreamSerializable serializable)
256+
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
257+
}
258+
}
259+
260+
public MultiSearchRequestDescriptor AddSearch(SearchRequestItem search)
261+
{
262+
_items.Add(search);
263+
return this;
264+
}
265+
}
266+
}

0 commit comments

Comments
 (0)