Skip to content

[Backport 8.4] Port TermsInclude type #6872

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 1 commit into from
Oct 31, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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;

namespace Elastic.Clients.Elasticsearch.Aggregations;

public partial class TermsAggregationDescriptor<TDocument>
{
public TermsAggregationDescriptor<TDocument> Include(long partition, long numberOfPartitions)
{
IncludeValue = new TermsInclude(partition, numberOfPartitions);
return Self;
}

public TermsAggregationDescriptor<TDocument> Include(string includeRegexPattern)
{
IncludeValue = new TermsInclude(includeRegexPattern);
return Self;
}

public TermsAggregationDescriptor<TDocument> Include(IEnumerable<string> values)
{
IncludeValue = new TermsInclude(values);
return Self;
}

public TermsAggregationDescriptor<TDocument> Exclude(string excludeRegexPattern)
{
ExcludeValue = new TermsExclude(excludeRegexPattern);
return Self;
}

public TermsAggregationDescriptor<TDocument> Exclude(IEnumerable<string> values)
{
ExcludeValue = new TermsExclude(values);
return Self;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Types.Aggregations;
#nullable enable
namespace Elastic.Clients.Elasticsearch.Aggregations;

/// <summary>
/// Filters which terms to exclude from the response.
Expand All @@ -20,14 +21,26 @@ public sealed class TermsExclude
/// to determine the terms to exclude from the response.
/// </summary>
/// <param name="pattern">The regular expression pattern.</param>
public TermsExclude(string regexPattern) => RegexPattern = regexPattern;
public TermsExclude(string regexPattern)
{
if (regexPattern is null)
throw new ArgumentNullException(nameof(regexPattern));

RegexPattern = regexPattern;
}

/// <summary>
/// Creates an instance of <see cref="TermsExclude" /> that uses a collection of terms
/// to exclude from the response.
/// </summary>
/// <param name="values">The exact terms to exclude.</param>
public TermsExclude(ICollection<string> values) => Values = values;
public TermsExclude(IEnumerable<string> values)
{
if (values is null)
throw new ArgumentNullException(nameof(values));

Values = values;
}

/// <summary>
/// The regular expression pattern to determine terms to exclude from the response.
Expand All @@ -37,7 +50,7 @@ public sealed class TermsExclude
/// <summary>
/// Collection of terms to exclude from the response.
/// </summary>
public ICollection<string>? Values { get; }
public IEnumerable<string>? Values { get; }
}

internal sealed class TermsExcludeConverter : JsonConverter<TermsExclude>
Expand All @@ -55,12 +68,12 @@ internal sealed class TermsExcludeConverter : JsonConverter<TermsExclude>
switch (reader.TokenType)
{
case JsonTokenType.StartArray:
var terms = JsonSerializer.Deserialize<IList<string>>(ref reader, options);
var terms = JsonSerializer.Deserialize<string[]>(ref reader, options) ?? Array.Empty<string>();
termsExclude = new TermsExclude(terms);
break;
case JsonTokenType.String:
var regex = reader.GetString();
termsExclude = new TermsExclude(regex);
termsExclude = new TermsExclude(regex!);
break;
default:
throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsExclude)}");
Expand All @@ -79,7 +92,7 @@ public override void Write(Utf8JsonWriter writer, TermsExclude value, JsonSerial

if (value.Values is not null)
{
JsonSerializer.Serialize<IEnumerable<string>>(writer, value.Values, options);
JsonSerializer.Serialize(writer, value.Values, options);
return;
}

Expand Down
158 changes: 158 additions & 0 deletions src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsInclude.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// 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;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable enable
namespace Elastic.Clients.Elasticsearch.Aggregations;

/// <summary>
/// Filters which terms to include in the response.
/// </summary>
[JsonConverter(typeof(TermsIncludeConverter))]
public class TermsInclude
{
/// <summary>
/// Creates an instance of <see cref="TermsInclude" /> that uses a regular expression pattern
/// to determine the terms to include in the response.
/// </summary>
/// <param name="regexPattern">The regular expression pattern.</param>
public TermsInclude(string regexPattern)
{
if (regexPattern is null)
throw new ArgumentNullException(nameof(regexPattern));

RegexPattern = regexPattern;
}

/// <summary>
/// Creates an instance of <see cref="TermsInclude" /> that uses a collection of terms
/// to include in the response.
/// </summary>
/// <param name="values">The exact terms to include.</param>
public TermsInclude(IEnumerable<string> values)
{
if (values is null)
throw new ArgumentNullException(nameof(values));

Values = values;
}

/// <summary>
/// Creates an instance of <see cref="TermsInclude" /> that partitions the terms into a number of
/// partitions to receive in multiple requests. Used to process many unique terms.
/// </summary>
/// <param name="partition">The 0-based partition number for this request.</param>
/// <param name="numberOfPartitions">The total number of partitions.</param>
public TermsInclude(long partition, long numberOfPartitions)
{
Partition = partition;
NumberOfPartitions = numberOfPartitions;
}

/// <summary>
/// The total number of partitions we are interested in.
/// </summary>
public long? NumberOfPartitions { get; }

/// <summary>
/// The current partition of terms we are interested in.
/// </summary>
public long? Partition { get; }

/// <summary>
/// The regular expression pattern to determine terms to include in the response.
/// </summary>
public string? RegexPattern { get; }

/// <summary>
/// Collection of terms to include in the response.
/// </summary>
public IEnumerable<string>? Values { get; }
}

internal sealed class TermsIncludeConverter : JsonConverter<TermsInclude>
{
public override TermsInclude? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
{
reader.Read();
return null;
}

TermsInclude termsInclude;

switch (reader.TokenType)
{
case JsonTokenType.StartArray:
var terms = JsonSerializer.Deserialize<string[]>(ref reader, options) ?? Array.Empty<string>();
termsInclude = new TermsInclude(terms);
break;
case JsonTokenType.StartObject:
long partition = 0;
long numberOfPartitions = 0;
while(reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "partition":
partition = reader.GetInt64();
break;
case "num_partitions":
numberOfPartitions = reader.GetInt64();
break;
default:
throw new JsonException($"Unexpected property name '{propertyName}' encountered when deserializing TermsInclude.");
}
}
}
termsInclude = new TermsInclude(partition, numberOfPartitions);
break;
case JsonTokenType.String:
var regex = reader.GetString();
termsInclude = new TermsInclude(regex!);
break;
default:
throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsInclude)}");
}

return termsInclude;
}

public override void Write(Utf8JsonWriter writer, TermsInclude value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}

if (value.Values is not null)
{
JsonSerializer.Serialize(writer, value.Values, options);
return;
}

if (value.Partition.HasValue && value.NumberOfPartitions.HasValue)
{
writer.WriteStartObject();
writer.WritePropertyName("partition");
writer.WriteNumberValue(value.Partition.Value);
writer.WritePropertyName("num_partitions");
writer.WriteNumberValue(value.NumberOfPartitions.Value);
writer.WriteEndObject();
return;
}

writer.WriteStringValue(value.RegexPattern);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ public override TermsAggregation Read(ref Utf8JsonReader reader, Type typeToConv
continue;
}

if (reader.ValueTextEquals("include"))
{
reader.Read();
var value = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Aggregations.TermsInclude?>(ref reader, options);
if (value is not null)
{
agg.Include = value;
}

continue;
}

if (reader.ValueTextEquals("min_doc_count"))
{
reader.Read();
Expand Down Expand Up @@ -288,6 +300,12 @@ public override void Write(Utf8JsonWriter writer, TermsAggregation value, JsonSe
writer.WriteStringValue(value.Format);
}

if (value.Include is not null)
{
writer.WritePropertyName("include");
JsonSerializer.Serialize(writer, value.Include, options);
}

if (value.MinDocCount.HasValue)
{
writer.WritePropertyName("min_doc_count");
Expand Down Expand Up @@ -385,6 +403,8 @@ internal TermsAggregation()

public string? Format { get; set; }

public Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? Include { get; set; }

public Dictionary<string, object>? Meta { get; set; }

public int? MinDocCount { get; set; }
Expand Down Expand Up @@ -434,6 +454,8 @@ public TermsAggregationDescriptor() : base()

private string? FormatValue { get; set; }

private Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? IncludeValue { get; set; }

private Dictionary<string, object>? MetaValue { get; set; }

private int? MinDocCountValue { get; set; }
Expand Down Expand Up @@ -516,6 +538,12 @@ public TermsAggregationDescriptor<TDocument> Format(string? format)
return Self;
}

public TermsAggregationDescriptor<TDocument> Include(Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? include)
{
IncludeValue = include;
return Self;
}

public TermsAggregationDescriptor<TDocument> Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
{
MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
Expand Down Expand Up @@ -617,6 +645,12 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
writer.WriteStringValue(FormatValue);
}

if (IncludeValue is not null)
{
writer.WritePropertyName("include");
JsonSerializer.Serialize(writer, IncludeValue, options);
}

if (MinDocCountValue.HasValue)
{
writer.WritePropertyName("min_doc_count");
Expand Down Expand Up @@ -727,6 +761,8 @@ public TermsAggregationDescriptor() : base()

private string? FormatValue { get; set; }

private Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? IncludeValue { get; set; }

private Dictionary<string, object>? MetaValue { get; set; }

private int? MinDocCountValue { get; set; }
Expand Down Expand Up @@ -815,6 +851,12 @@ public TermsAggregationDescriptor Format(string? format)
return Self;
}

public TermsAggregationDescriptor Include(Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? include)
{
IncludeValue = include;
return Self;
}

public TermsAggregationDescriptor Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
{
MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
Expand Down Expand Up @@ -916,6 +958,12 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
writer.WriteStringValue(FormatValue);
}

if (IncludeValue is not null)
{
writer.WritePropertyName("include");
JsonSerializer.Serialize(writer, IncludeValue, options);
}

if (MinDocCountValue.HasValue)
{
writer.WritePropertyName("min_doc_count");
Expand Down
Loading