Skip to content

Add support for MSearch #6445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions build/scripts/scripts.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<OutputType>Exe</OutputType>
<!-- Type Providers are restored using net461, fine for netcoreapp2.2 so we kill the warning -->
<NoWarn>$(NoWarn);NU1701</NoWarn>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
</PropertyGroup>
<ItemGroup>
<Compile Include="Commandline.fs" />
Expand Down Expand Up @@ -34,17 +35,15 @@
<Content Include="..\..\.github\workflows\make-release-notes.yml"><Link>make-release-notes.yml</Link></Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Core" Version="6.0.4" /> <!-- Hardcoded for manual control over the version, otherwise this updates when the SDK updates. -->
<PackageReference Include="Bullseye" Version="3.3.0" />
<PackageReference Include="Elastic.Elasticsearch.Managed" Version="0.3.0" />

<PackageReference Include="Fake.Core.Environment" Version="5.15.0" />
<PackageReference Include="Fake.Core.SemVer" Version="5.15.0" />
<PackageReference Include="Fake.IO.FileSystem" Version="5.15.0" />
<PackageReference Include="Fake.IO.Zip" Version="5.15.0" />
<PackageReference Include="Fake.Tools.Git" Version="5.15.0" />

<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />

<PackageReference Include="Octokit" Version="0.32.0" />
<PackageReference Include="Proc" Version="0.6.1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Elastic.Transport;

namespace Elastic.Clients.Elasticsearch
{
public sealed partial class MultiSearchRequestDescriptor<TDocument>
{
internal override void BeforeRequest() => TypedKeys(true);
}

public sealed partial class MultiSearchRequestDescriptor
{
internal override void BeforeRequest() => TypedKeys(true);
}

public partial class MultiSearchRequest
{
internal override void BeforeRequest() => TypedKeys = true;
}

// POC - If we have more than one union doing this, can we autogenerate with correct ctors etc.
public class SearchRequestItem : IStreamSerializable
{
public SearchRequestItem(MultisearchBody body) => Body = body;

public SearchRequestItem(MultisearchHeader header, MultisearchBody body)
{
Header = header;
Body = body;
}

public MultisearchHeader Header { get; init; }
public MultisearchBody Body { get; init; }

void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Body is null)
return;

if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
{
JsonSerializer.Serialize(stream, Header, options);
stream.WriteByte((byte)'\n');
JsonSerializer.Serialize(stream, Body, options);
stream.WriteByte((byte)'\n');
}
}

async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Body is null)
return;

if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
{
await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false);
stream.WriteByte((byte)'\n');
await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false);
stream.WriteByte((byte)'\n');
}
}
}

public partial class ResponseBody<TDocument>
{
[JsonIgnore]
public IReadOnlyCollection<Hit<TDocument>> Hits => HitsMetadata.Hits;

[JsonIgnore]
public IReadOnlyCollection<TDocument> Documents => HitsMetadata.Hits.Select(s => s.Source).ToReadOnlyCollection();

[JsonIgnore]
public long Total => HitsMetadata?.Total?.Value ?? -1;
}

public partial class MultiSearchResponse<TDocument>
{
public override bool IsValid => base.IsValid && (Responses?.All(b => b.Item1 is not null && b.Item1.Status == 200) ?? true);

[JsonIgnore]
public int TotalResponses => Responses.HasAny() ? Responses.Count() : 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ internal static class ApiUrlsLookups
internal static ApiUrls MachineLearningValidateDetector = new ApiUrls(new[] { "/_ml/anomaly_detectors/_validate/detector" });
internal static ApiUrls MachineLearningValidate = new ApiUrls(new[] { "/_ml/anomaly_detectors/_validate" });
internal static ApiUrls NoNamespaceMget = new ApiUrls(new[] { "/_mget", "/{index}/_mget" });
internal static ApiUrls NoNamespaceMsearch = new ApiUrls(new[] { "/_msearch", "/{index}/_msearch" });
internal static ApiUrls NodesHotThreads = new ApiUrls(new[] { "/_nodes/hot_threads", "/_nodes/{node_id}/hot_threads" });
internal static ApiUrls NodesInfo = new ApiUrls(new[] { "/_nodes", "/_nodes/{node_id}", "/_nodes/{metric}", "/_nodes/{node_id}/{metric}" });
internal static ApiUrls NodesReloadSecureSettings = new ApiUrls(new[] { "/_nodes/reload_secure_settings", "/_nodes/{node_id}/reload_secure_settings" });
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗
// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝
// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗
// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

using Elastic.Transport;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

#nullable restore
namespace Elastic.Clients.Elasticsearch
{
public sealed class MultiSearchRequestParameters : RequestParameters<MultiSearchRequestParameters>
{
[JsonIgnore]
public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

[JsonIgnore]
public bool? CcsMinimizeRoundtrips { get => Q<bool?>("ccs_minimize_roundtrips"); set => Q("ccs_minimize_roundtrips", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.ExpandWildcards? ExpandWildcards { get => Q<Elastic.Clients.Elasticsearch.ExpandWildcards?>("expand_wildcards"); set => Q("expand_wildcards", value); }

[JsonIgnore]
public bool? IgnoreThrottled { get => Q<bool?>("ignore_throttled"); set => Q("ignore_throttled", value); }

[JsonIgnore]
public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }

[JsonIgnore]
public long? MaxConcurrentSearches { get => Q<long?>("max_concurrent_searches"); set => Q("max_concurrent_searches", value); }

[JsonIgnore]
public long? MaxConcurrentShardRequests { get => Q<long?>("max_concurrent_shard_requests"); set => Q("max_concurrent_shard_requests", value); }

[JsonIgnore]
public long? PreFilterShardSize { get => Q<long?>("pre_filter_shard_size"); set => Q("pre_filter_shard_size", value); }

[JsonIgnore]
public bool? RestTotalHitsAsInt { get => Q<bool?>("rest_total_hits_as_int"); set => Q("rest_total_hits_as_int", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.Routing? Routing { get => Q<Elastic.Clients.Elasticsearch.Routing?>("routing"); set => Q("routing", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.SearchType? SearchType { get => Q<Elastic.Clients.Elasticsearch.SearchType?>("search_type"); set => Q("search_type", value); }

[JsonIgnore]
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }
}

public partial class MultiSearchRequest : PlainRequestBase<MultiSearchRequestParameters>, IStreamSerializable
{
public MultiSearchRequest()
{
}

public MultiSearchRequest(Elastic.Clients.Elasticsearch.Indices? indices) : base(r => r.Optional("index", indices))
{
}

internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
protected override HttpMethod HttpMethod => HttpMethod.POST;
protected override bool SupportsBody => true;
[JsonIgnore]
public bool? AllowNoIndices { get => Q<bool?>("allow_no_indices"); set => Q("allow_no_indices", value); }

[JsonIgnore]
public bool? CcsMinimizeRoundtrips { get => Q<bool?>("ccs_minimize_roundtrips"); set => Q("ccs_minimize_roundtrips", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.ExpandWildcards? ExpandWildcards { get => Q<Elastic.Clients.Elasticsearch.ExpandWildcards?>("expand_wildcards"); set => Q("expand_wildcards", value); }

[JsonIgnore]
public bool? IgnoreThrottled { get => Q<bool?>("ignore_throttled"); set => Q("ignore_throttled", value); }

[JsonIgnore]
public bool? IgnoreUnavailable { get => Q<bool?>("ignore_unavailable"); set => Q("ignore_unavailable", value); }

[JsonIgnore]
public long? MaxConcurrentSearches { get => Q<long?>("max_concurrent_searches"); set => Q("max_concurrent_searches", value); }

[JsonIgnore]
public long? MaxConcurrentShardRequests { get => Q<long?>("max_concurrent_shard_requests"); set => Q("max_concurrent_shard_requests", value); }

[JsonIgnore]
public long? PreFilterShardSize { get => Q<long?>("pre_filter_shard_size"); set => Q("pre_filter_shard_size", value); }

[JsonIgnore]
public bool? RestTotalHitsAsInt { get => Q<bool?>("rest_total_hits_as_int"); set => Q("rest_total_hits_as_int", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.Routing? Routing { get => Q<Elastic.Clients.Elasticsearch.Routing?>("routing"); set => Q("routing", value); }

[JsonIgnore]
public Elastic.Clients.Elasticsearch.SearchType? SearchType { get => Q<Elastic.Clients.Elasticsearch.SearchType?>("search_type"); set => Q("search_type", value); }

[JsonIgnore]
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }

public List<SearchRequestItem> Searches { get; set; }

void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Searches is null)
return;
foreach (var item in Searches)
{
if (item is IStreamSerializable serializable)
serializable.Serialize(stream, settings, formatting);
}
}

async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Searches is null)
return;
foreach (var item in Searches)
{
if (item is IStreamSerializable serializable)
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
}
}
}

public sealed partial class MultiSearchRequestDescriptor<TDocument> : RequestDescriptorBase<MultiSearchRequestDescriptor<TDocument>, MultiSearchRequestParameters>, IStreamSerializable
{
internal MultiSearchRequestDescriptor(Action<MultiSearchRequestDescriptor<TDocument>> configure) => configure.Invoke(this);
public MultiSearchRequestDescriptor()
{
}

internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
protected override HttpMethod HttpMethod => HttpMethod.POST;
protected override bool SupportsBody => true;
public MultiSearchRequestDescriptor<TDocument> AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
public MultiSearchRequestDescriptor<TDocument> CcsMinimizeRoundtrips(bool? ccsMinimizeRoundtrips = true) => Qs("ccs_minimize_roundtrips", ccsMinimizeRoundtrips);
public MultiSearchRequestDescriptor<TDocument> ExpandWildcards(Elastic.Clients.Elasticsearch.ExpandWildcards? expandWildcards) => Qs("expand_wildcards", expandWildcards);
public MultiSearchRequestDescriptor<TDocument> IgnoreThrottled(bool? ignoreThrottled = true) => Qs("ignore_throttled", ignoreThrottled);
public MultiSearchRequestDescriptor<TDocument> IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);
public MultiSearchRequestDescriptor<TDocument> MaxConcurrentSearches(long? maxConcurrentSearches) => Qs("max_concurrent_searches", maxConcurrentSearches);
public MultiSearchRequestDescriptor<TDocument> MaxConcurrentShardRequests(long? maxConcurrentShardRequests) => Qs("max_concurrent_shard_requests", maxConcurrentShardRequests);
public MultiSearchRequestDescriptor<TDocument> PreFilterShardSize(long? preFilterShardSize) => Qs("pre_filter_shard_size", preFilterShardSize);
public MultiSearchRequestDescriptor<TDocument> RestTotalHitsAsInt(bool? restTotalHitsAsInt = true) => Qs("rest_total_hits_as_int", restTotalHitsAsInt);
public MultiSearchRequestDescriptor<TDocument> Routing(Elastic.Clients.Elasticsearch.Routing? routing) => Qs("routing", routing);
public MultiSearchRequestDescriptor<TDocument> SearchType(Elastic.Clients.Elasticsearch.SearchType? searchType) => Qs("search_type", searchType);
public MultiSearchRequestDescriptor<TDocument> TypedKeys(bool? typedKeys = true) => Qs("typed_keys", typedKeys);
public MultiSearchRequestDescriptor<TDocument> Indices(Elastic.Clients.Elasticsearch.Indices? indices)
{
RouteValues.Optional("index", indices);
return Self;
}

protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
{
}

List<SearchRequestItem> _items = new();
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (_items is null)
return;
foreach (var item in _items)
{
if (item is IStreamSerializable serializable)
serializable.Serialize(stream, settings, formatting);
}
}

async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (_items is null)
return;
foreach (var item in _items)
{
if (item is IStreamSerializable serializable)
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
}
}

public MultiSearchRequestDescriptor<TDocument> AddSearch(SearchRequestItem search)
{
_items.Add(search);
return this;
}
}

public sealed partial class MultiSearchRequestDescriptor : RequestDescriptorBase<MultiSearchRequestDescriptor, MultiSearchRequestParameters>, IStreamSerializable
{
internal MultiSearchRequestDescriptor(Action<MultiSearchRequestDescriptor> configure) => configure.Invoke(this);
public MultiSearchRequestDescriptor()
{
}

internal override ApiUrls ApiUrls => ApiUrlsLookups.NoNamespaceMsearch;
protected override HttpMethod HttpMethod => HttpMethod.POST;
protected override bool SupportsBody => true;
public MultiSearchRequestDescriptor AllowNoIndices(bool? allowNoIndices = true) => Qs("allow_no_indices", allowNoIndices);
public MultiSearchRequestDescriptor CcsMinimizeRoundtrips(bool? ccsMinimizeRoundtrips = true) => Qs("ccs_minimize_roundtrips", ccsMinimizeRoundtrips);
public MultiSearchRequestDescriptor ExpandWildcards(Elastic.Clients.Elasticsearch.ExpandWildcards? expandWildcards) => Qs("expand_wildcards", expandWildcards);
public MultiSearchRequestDescriptor IgnoreThrottled(bool? ignoreThrottled = true) => Qs("ignore_throttled", ignoreThrottled);
public MultiSearchRequestDescriptor IgnoreUnavailable(bool? ignoreUnavailable = true) => Qs("ignore_unavailable", ignoreUnavailable);
public MultiSearchRequestDescriptor MaxConcurrentSearches(long? maxConcurrentSearches) => Qs("max_concurrent_searches", maxConcurrentSearches);
public MultiSearchRequestDescriptor MaxConcurrentShardRequests(long? maxConcurrentShardRequests) => Qs("max_concurrent_shard_requests", maxConcurrentShardRequests);
public MultiSearchRequestDescriptor PreFilterShardSize(long? preFilterShardSize) => Qs("pre_filter_shard_size", preFilterShardSize);
public MultiSearchRequestDescriptor RestTotalHitsAsInt(bool? restTotalHitsAsInt = true) => Qs("rest_total_hits_as_int", restTotalHitsAsInt);
public MultiSearchRequestDescriptor Routing(Elastic.Clients.Elasticsearch.Routing? routing) => Qs("routing", routing);
public MultiSearchRequestDescriptor SearchType(Elastic.Clients.Elasticsearch.SearchType? searchType) => Qs("search_type", searchType);
public MultiSearchRequestDescriptor TypedKeys(bool? typedKeys = true) => Qs("typed_keys", typedKeys);
public MultiSearchRequestDescriptor Indices(Elastic.Clients.Elasticsearch.Indices? indices)
{
RouteValues.Optional("index", indices);
return Self;
}

protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
{
}

List<SearchRequestItem> _items = new();
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (_items is null)
return;
foreach (var item in _items)
{
if (item is IStreamSerializable serializable)
serializable.Serialize(stream, settings, formatting);
}
}

async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (_items is null)
return;
foreach (var item in _items)
{
if (item is IStreamSerializable serializable)
await serializable.SerializeAsync(stream, settings, formatting).ConfigureAwait(false);
}
}

public MultiSearchRequestDescriptor AddSearch(SearchRequestItem search)
{
_items.Add(search);
return this;
}
}
}
Loading