Skip to content

Commit d45c863

Browse files
Support TermsInclude (#6867) (#6872)
Co-authored-by: Steve Gordon <sgordon@hotmail.co.uk>
1 parent a068aaf commit d45c863

13 files changed

+395
-17
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
7+
namespace Elastic.Clients.Elasticsearch.Aggregations;
8+
9+
public partial class TermsAggregationDescriptor<TDocument>
10+
{
11+
public TermsAggregationDescriptor<TDocument> Include(long partition, long numberOfPartitions)
12+
{
13+
IncludeValue = new TermsInclude(partition, numberOfPartitions);
14+
return Self;
15+
}
16+
17+
public TermsAggregationDescriptor<TDocument> Include(string includeRegexPattern)
18+
{
19+
IncludeValue = new TermsInclude(includeRegexPattern);
20+
return Self;
21+
}
22+
23+
public TermsAggregationDescriptor<TDocument> Include(IEnumerable<string> values)
24+
{
25+
IncludeValue = new TermsInclude(values);
26+
return Self;
27+
}
28+
29+
public TermsAggregationDescriptor<TDocument> Exclude(string excludeRegexPattern)
30+
{
31+
ExcludeValue = new TermsExclude(excludeRegexPattern);
32+
return Self;
33+
}
34+
35+
public TermsAggregationDescriptor<TDocument> Exclude(IEnumerable<string> values)
36+
{
37+
ExcludeValue = new TermsExclude(values);
38+
return Self;
39+
}
40+
}

src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsExclude.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
using System.Text.Json;
88
using System.Text.Json.Serialization;
99

10-
namespace Elastic.Clients.Elasticsearch.Types.Aggregations;
10+
#nullable enable
11+
namespace Elastic.Clients.Elasticsearch.Aggregations;
1112

1213
/// <summary>
1314
/// Filters which terms to exclude from the response.
@@ -20,14 +21,26 @@ public sealed class TermsExclude
2021
/// to determine the terms to exclude from the response.
2122
/// </summary>
2223
/// <param name="pattern">The regular expression pattern.</param>
23-
public TermsExclude(string regexPattern) => RegexPattern = regexPattern;
24+
public TermsExclude(string regexPattern)
25+
{
26+
if (regexPattern is null)
27+
throw new ArgumentNullException(nameof(regexPattern));
28+
29+
RegexPattern = regexPattern;
30+
}
2431

2532
/// <summary>
2633
/// Creates an instance of <see cref="TermsExclude" /> that uses a collection of terms
2734
/// to exclude from the response.
2835
/// </summary>
2936
/// <param name="values">The exact terms to exclude.</param>
30-
public TermsExclude(ICollection<string> values) => Values = values;
37+
public TermsExclude(IEnumerable<string> values)
38+
{
39+
if (values is null)
40+
throw new ArgumentNullException(nameof(values));
41+
42+
Values = values;
43+
}
3144

3245
/// <summary>
3346
/// The regular expression pattern to determine terms to exclude from the response.
@@ -37,7 +50,7 @@ public sealed class TermsExclude
3750
/// <summary>
3851
/// Collection of terms to exclude from the response.
3952
/// </summary>
40-
public ICollection<string>? Values { get; }
53+
public IEnumerable<string>? Values { get; }
4154
}
4255

4356
internal sealed class TermsExcludeConverter : JsonConverter<TermsExclude>
@@ -55,12 +68,12 @@ internal sealed class TermsExcludeConverter : JsonConverter<TermsExclude>
5568
switch (reader.TokenType)
5669
{
5770
case JsonTokenType.StartArray:
58-
var terms = JsonSerializer.Deserialize<IList<string>>(ref reader, options);
71+
var terms = JsonSerializer.Deserialize<string[]>(ref reader, options) ?? Array.Empty<string>();
5972
termsExclude = new TermsExclude(terms);
6073
break;
6174
case JsonTokenType.String:
6275
var regex = reader.GetString();
63-
termsExclude = new TermsExclude(regex);
76+
termsExclude = new TermsExclude(regex!);
6477
break;
6578
default:
6679
throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsExclude)}");
@@ -79,7 +92,7 @@ public override void Write(Utf8JsonWriter writer, TermsExclude value, JsonSerial
7992

8093
if (value.Values is not null)
8194
{
82-
JsonSerializer.Serialize<IEnumerable<string>>(writer, value.Values, options);
95+
JsonSerializer.Serialize(writer, value.Values, options);
8396
return;
8497
}
8598

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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;
6+
using System.Collections.Generic;
7+
using System.Text.Json;
8+
using System.Text.Json.Serialization;
9+
10+
#nullable enable
11+
namespace Elastic.Clients.Elasticsearch.Aggregations;
12+
13+
/// <summary>
14+
/// Filters which terms to include in the response.
15+
/// </summary>
16+
[JsonConverter(typeof(TermsIncludeConverter))]
17+
public class TermsInclude
18+
{
19+
/// <summary>
20+
/// Creates an instance of <see cref="TermsInclude" /> that uses a regular expression pattern
21+
/// to determine the terms to include in the response.
22+
/// </summary>
23+
/// <param name="regexPattern">The regular expression pattern.</param>
24+
public TermsInclude(string regexPattern)
25+
{
26+
if (regexPattern is null)
27+
throw new ArgumentNullException(nameof(regexPattern));
28+
29+
RegexPattern = regexPattern;
30+
}
31+
32+
/// <summary>
33+
/// Creates an instance of <see cref="TermsInclude" /> that uses a collection of terms
34+
/// to include in the response.
35+
/// </summary>
36+
/// <param name="values">The exact terms to include.</param>
37+
public TermsInclude(IEnumerable<string> values)
38+
{
39+
if (values is null)
40+
throw new ArgumentNullException(nameof(values));
41+
42+
Values = values;
43+
}
44+
45+
/// <summary>
46+
/// Creates an instance of <see cref="TermsInclude" /> that partitions the terms into a number of
47+
/// partitions to receive in multiple requests. Used to process many unique terms.
48+
/// </summary>
49+
/// <param name="partition">The 0-based partition number for this request.</param>
50+
/// <param name="numberOfPartitions">The total number of partitions.</param>
51+
public TermsInclude(long partition, long numberOfPartitions)
52+
{
53+
Partition = partition;
54+
NumberOfPartitions = numberOfPartitions;
55+
}
56+
57+
/// <summary>
58+
/// The total number of partitions we are interested in.
59+
/// </summary>
60+
public long? NumberOfPartitions { get; }
61+
62+
/// <summary>
63+
/// The current partition of terms we are interested in.
64+
/// </summary>
65+
public long? Partition { get; }
66+
67+
/// <summary>
68+
/// The regular expression pattern to determine terms to include in the response.
69+
/// </summary>
70+
public string? RegexPattern { get; }
71+
72+
/// <summary>
73+
/// Collection of terms to include in the response.
74+
/// </summary>
75+
public IEnumerable<string>? Values { get; }
76+
}
77+
78+
internal sealed class TermsIncludeConverter : JsonConverter<TermsInclude>
79+
{
80+
public override TermsInclude? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
81+
{
82+
if (reader.TokenType == JsonTokenType.Null)
83+
{
84+
reader.Read();
85+
return null;
86+
}
87+
88+
TermsInclude termsInclude;
89+
90+
switch (reader.TokenType)
91+
{
92+
case JsonTokenType.StartArray:
93+
var terms = JsonSerializer.Deserialize<string[]>(ref reader, options) ?? Array.Empty<string>();
94+
termsInclude = new TermsInclude(terms);
95+
break;
96+
case JsonTokenType.StartObject:
97+
long partition = 0;
98+
long numberOfPartitions = 0;
99+
while(reader.Read() && reader.TokenType != JsonTokenType.EndObject)
100+
{
101+
if (reader.TokenType == JsonTokenType.PropertyName)
102+
{
103+
var propertyName = reader.GetString();
104+
reader.Read();
105+
switch (propertyName)
106+
{
107+
case "partition":
108+
partition = reader.GetInt64();
109+
break;
110+
case "num_partitions":
111+
numberOfPartitions = reader.GetInt64();
112+
break;
113+
default:
114+
throw new JsonException($"Unexpected property name '{propertyName}' encountered when deserializing TermsInclude.");
115+
}
116+
}
117+
}
118+
termsInclude = new TermsInclude(partition, numberOfPartitions);
119+
break;
120+
case JsonTokenType.String:
121+
var regex = reader.GetString();
122+
termsInclude = new TermsInclude(regex!);
123+
break;
124+
default:
125+
throw new JsonException($"Unexpected token {reader.TokenType} when deserializing {nameof(TermsInclude)}");
126+
}
127+
128+
return termsInclude;
129+
}
130+
131+
public override void Write(Utf8JsonWriter writer, TermsInclude value, JsonSerializerOptions options)
132+
{
133+
if (value is null)
134+
{
135+
writer.WriteNullValue();
136+
return;
137+
}
138+
139+
if (value.Values is not null)
140+
{
141+
JsonSerializer.Serialize(writer, value.Values, options);
142+
return;
143+
}
144+
145+
if (value.Partition.HasValue && value.NumberOfPartitions.HasValue)
146+
{
147+
writer.WriteStartObject();
148+
writer.WritePropertyName("partition");
149+
writer.WriteNumberValue(value.Partition.Value);
150+
writer.WritePropertyName("num_partitions");
151+
writer.WriteNumberValue(value.NumberOfPartitions.Value);
152+
writer.WriteEndObject();
153+
return;
154+
}
155+
156+
writer.WriteStringValue(value.RegexPattern);
157+
}
158+
}

src/Elastic.Clients.Elasticsearch/_Generated/Types/Aggregations/TermsAggregation.g.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ public override TermsAggregation Read(ref Utf8JsonReader reader, Type typeToConv
100100
continue;
101101
}
102102

103+
if (reader.ValueTextEquals("include"))
104+
{
105+
reader.Read();
106+
var value = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Aggregations.TermsInclude?>(ref reader, options);
107+
if (value is not null)
108+
{
109+
agg.Include = value;
110+
}
111+
112+
continue;
113+
}
114+
103115
if (reader.ValueTextEquals("min_doc_count"))
104116
{
105117
reader.Read();
@@ -288,6 +300,12 @@ public override void Write(Utf8JsonWriter writer, TermsAggregation value, JsonSe
288300
writer.WriteStringValue(value.Format);
289301
}
290302

303+
if (value.Include is not null)
304+
{
305+
writer.WritePropertyName("include");
306+
JsonSerializer.Serialize(writer, value.Include, options);
307+
}
308+
291309
if (value.MinDocCount.HasValue)
292310
{
293311
writer.WritePropertyName("min_doc_count");
@@ -385,6 +403,8 @@ internal TermsAggregation()
385403

386404
public string? Format { get; set; }
387405

406+
public Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? Include { get; set; }
407+
388408
public Dictionary<string, object>? Meta { get; set; }
389409

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

435455
private string? FormatValue { get; set; }
436456

457+
private Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? IncludeValue { get; set; }
458+
437459
private Dictionary<string, object>? MetaValue { get; set; }
438460

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

541+
public TermsAggregationDescriptor<TDocument> Include(Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? include)
542+
{
543+
IncludeValue = include;
544+
return Self;
545+
}
546+
519547
public TermsAggregationDescriptor<TDocument> Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
520548
{
521549
MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
@@ -617,6 +645,12 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
617645
writer.WriteStringValue(FormatValue);
618646
}
619647

648+
if (IncludeValue is not null)
649+
{
650+
writer.WritePropertyName("include");
651+
JsonSerializer.Serialize(writer, IncludeValue, options);
652+
}
653+
620654
if (MinDocCountValue.HasValue)
621655
{
622656
writer.WritePropertyName("min_doc_count");
@@ -727,6 +761,8 @@ public TermsAggregationDescriptor() : base()
727761

728762
private string? FormatValue { get; set; }
729763

764+
private Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? IncludeValue { get; set; }
765+
730766
private Dictionary<string, object>? MetaValue { get; set; }
731767

732768
private int? MinDocCountValue { get; set; }
@@ -815,6 +851,12 @@ public TermsAggregationDescriptor Format(string? format)
815851
return Self;
816852
}
817853

854+
public TermsAggregationDescriptor Include(Elastic.Clients.Elasticsearch.Aggregations.TermsInclude? include)
855+
{
856+
IncludeValue = include;
857+
return Self;
858+
}
859+
818860
public TermsAggregationDescriptor Meta(Func<FluentDictionary<string, object>, FluentDictionary<string, object>> selector)
819861
{
820862
MetaValue = selector?.Invoke(new FluentDictionary<string, object>());
@@ -916,6 +958,12 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
916958
writer.WriteStringValue(FormatValue);
917959
}
918960

961+
if (IncludeValue is not null)
962+
{
963+
writer.WritePropertyName("include");
964+
JsonSerializer.Serialize(writer, IncludeValue, options);
965+
}
966+
919967
if (MinDocCountValue.HasValue)
920968
{
921969
writer.WritePropertyName("min_doc_count");

0 commit comments

Comments
 (0)