From 778bd517210a1e0704287bfcda931dafb48a2819 Mon Sep 17 00:00:00 2001 From: Florian Bernd Date: Fri, 26 Apr 2024 16:37:23 +0200 Subject: [PATCH] Implement `TermsRangeQuery` --- .../_Generated/Types/QueryDsl/RangeQuery.g.cs | 42 -- .../Types/QueryDsl/TermsRangeQuery.g.cs | 566 ++++++++++++++++++ .../Core/DateTime/DateMath/DateMath.cs | 2 +- .../Core/Infer/Field/Field.cs | 2 +- .../Core/Infer/Fields/Fields.cs | 2 +- .../Types/QueryDsl/RangeQuery.cs | 147 +++++ .../_Generated/Types/QueryDsl/RangeQuery.g.cs | 42 -- .../Types/QueryDsl/TermsRangeQuery.g.cs | 566 ++++++++++++++++++ 8 files changed, 1282 insertions(+), 87 deletions(-) delete mode 100644 src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/RangeQuery.g.cs create mode 100644 src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs delete mode 100644 src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/RangeQuery.g.cs create mode 100644 src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/RangeQuery.g.cs b/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/RangeQuery.g.cs deleted file mode 100644 index 7efbdcec56c..00000000000 --- a/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/RangeQuery.g.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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. -// -// ------------------------------------------------ - -#nullable restore - -using Elastic.Clients.Elasticsearch.Serverless.Core; -using Elastic.Clients.Elasticsearch.Serverless.Fluent; -using Elastic.Clients.Elasticsearch.Serverless.Serialization; -using Elastic.Transport; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq.Expressions; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch.Serverless.QueryDsl; - -public sealed partial class RangeQuery : Union -{ - public RangeQuery(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.DateRangeQuery Date) : base(Date) - { - } - - public RangeQuery(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.NumberRangeQuery Number) : base(Number) - { - } -} \ No newline at end of file diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs b/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs new file mode 100644 index 00000000000..d5cb5536fe3 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch.Serverless/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs @@ -0,0 +1,566 @@ +// 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. +// +// ------------------------------------------------ + +#nullable restore + +using Elastic.Clients.Elasticsearch.Serverless.Fluent; +using Elastic.Clients.Elasticsearch.Serverless.Serialization; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.Serverless.QueryDsl; + +internal sealed partial class TermsRangeQueryConverter : JsonConverter +{ + public override TermsRangeQuery Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Unexpected JSON detected."); + reader.Read(); + var fieldName = reader.GetString(); + reader.Read(); + var variant = new TermsRangeQuery(fieldName); + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType == JsonTokenType.PropertyName) + { + var property = reader.GetString(); + if (property == "boost") + { + variant.Boost = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "from") + { + variant.From = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "gt") + { + variant.Gt = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "gte") + { + variant.Gte = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "lt") + { + variant.Lt = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "lte") + { + variant.Lte = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "_name") + { + variant.QueryName = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "relation") + { + variant.Relation = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "to") + { + variant.To = JsonSerializer.Deserialize(ref reader, options); + continue; + } + } + } + + reader.Read(); + return variant; + } + + public override void Write(Utf8JsonWriter writer, TermsRangeQuery value, JsonSerializerOptions options) + { + if (value.Field is null) + throw new JsonException("Unable to serialize TermsRangeQuery because the `Field` property is not set. Field name queries must include a valid field name."); + if (!options.TryGetClientSettings(out var settings)) + throw new JsonException("Unable to retrieve client settings required to infer field."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(value.Field)); + writer.WriteStartObject(); + if (value.Boost.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(value.Boost.Value); + } + + if (!string.IsNullOrEmpty(value.From)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(value.From); + } + + if (!string.IsNullOrEmpty(value.Gt)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(value.Gt); + } + + if (!string.IsNullOrEmpty(value.Gte)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(value.Gte); + } + + if (!string.IsNullOrEmpty(value.Lt)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(value.Lt); + } + + if (!string.IsNullOrEmpty(value.Lte)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(value.Lte); + } + + if (!string.IsNullOrEmpty(value.QueryName)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(value.QueryName); + } + + if (value.Relation is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, value.Relation, options); + } + + if (!string.IsNullOrEmpty(value.To)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(value.To); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} + +[JsonConverter(typeof(TermsRangeQueryConverter))] +public sealed partial class TermsRangeQuery +{ + public TermsRangeQuery(Elastic.Clients.Elasticsearch.Serverless.Field field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + Field = field; + } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public float? Boost { get; set; } + public Elastic.Clients.Elasticsearch.Serverless.Field Field { get; set; } + public string? From { get; set; } + + /// + /// Greater than. + /// + public string? Gt { get; set; } + + /// + /// Greater than or equal to. + /// + public string? Gte { get; set; } + + /// + /// Less than. + /// + public string? Lt { get; set; } + + /// + /// Less than or equal to. + /// + public string? Lte { get; set; } + public string? QueryName { get; set; } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public Elastic.Clients.Elasticsearch.Serverless.QueryDsl.RangeRelation? Relation { get; set; } + public string? To { get; set; } +} + +public sealed partial class TermsRangeQueryDescriptor : SerializableDescriptor> +{ + internal TermsRangeQueryDescriptor(Action> configure) => configure.Invoke(this); + + public TermsRangeQueryDescriptor() : base() + { + } + + private float? BoostValue { get; set; } + private Elastic.Clients.Elasticsearch.Serverless.Field FieldValue { get; set; } + private string? FromValue { get; set; } + private string? GtValue { get; set; } + private string? GteValue { get; set; } + private string? LtValue { get; set; } + private string? LteValue { get; set; } + private string? QueryNameValue { get; set; } + private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.RangeRelation? RelationValue { get; set; } + private string? ToValue { get; set; } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public TermsRangeQueryDescriptor Boost(float? boost) + { + BoostValue = boost; + return Self; + } + + public TermsRangeQueryDescriptor Field(Elastic.Clients.Elasticsearch.Serverless.Field field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor From(string? from) + { + FromValue = from; + return Self; + } + + /// + /// Greater than. + /// + public TermsRangeQueryDescriptor Gt(string? gt) + { + GtValue = gt; + return Self; + } + + /// + /// Greater than or equal to. + /// + public TermsRangeQueryDescriptor Gte(string? gte) + { + GteValue = gte; + return Self; + } + + /// + /// Less than. + /// + public TermsRangeQueryDescriptor Lt(string? lt) + { + LtValue = lt; + return Self; + } + + /// + /// Less than or equal to. + /// + public TermsRangeQueryDescriptor Lte(string? lte) + { + LteValue = lte; + return Self; + } + + public TermsRangeQueryDescriptor QueryName(string? queryName) + { + QueryNameValue = queryName; + return Self; + } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public TermsRangeQueryDescriptor Relation(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.RangeRelation? relation) + { + RelationValue = relation; + return Self; + } + + public TermsRangeQueryDescriptor To(string? to) + { + ToValue = to; + return Self; + } + + protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + if (FieldValue is null) + throw new JsonException("Unable to serialize field name query descriptor with a null field. Ensure you use a suitable descriptor constructor or call the Field method, passing a non-null value for the field argument."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(FieldValue)); + writer.WriteStartObject(); + if (BoostValue.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(BoostValue.Value); + } + + if (!string.IsNullOrEmpty(FromValue)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(FromValue); + } + + if (!string.IsNullOrEmpty(GtValue)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(GtValue); + } + + if (!string.IsNullOrEmpty(GteValue)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(GteValue); + } + + if (!string.IsNullOrEmpty(LtValue)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(LtValue); + } + + if (!string.IsNullOrEmpty(LteValue)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(LteValue); + } + + if (!string.IsNullOrEmpty(QueryNameValue)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(QueryNameValue); + } + + if (RelationValue is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, RelationValue, options); + } + + if (!string.IsNullOrEmpty(ToValue)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(ToValue); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} + +public sealed partial class TermsRangeQueryDescriptor : SerializableDescriptor +{ + internal TermsRangeQueryDescriptor(Action configure) => configure.Invoke(this); + + public TermsRangeQueryDescriptor() : base() + { + } + + private float? BoostValue { get; set; } + private Elastic.Clients.Elasticsearch.Serverless.Field FieldValue { get; set; } + private string? FromValue { get; set; } + private string? GtValue { get; set; } + private string? GteValue { get; set; } + private string? LtValue { get; set; } + private string? LteValue { get; set; } + private string? QueryNameValue { get; set; } + private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.RangeRelation? RelationValue { get; set; } + private string? ToValue { get; set; } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public TermsRangeQueryDescriptor Boost(float? boost) + { + BoostValue = boost; + return Self; + } + + public TermsRangeQueryDescriptor Field(Elastic.Clients.Elasticsearch.Serverless.Field field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor From(string? from) + { + FromValue = from; + return Self; + } + + /// + /// Greater than. + /// + public TermsRangeQueryDescriptor Gt(string? gt) + { + GtValue = gt; + return Self; + } + + /// + /// Greater than or equal to. + /// + public TermsRangeQueryDescriptor Gte(string? gte) + { + GteValue = gte; + return Self; + } + + /// + /// Less than. + /// + public TermsRangeQueryDescriptor Lt(string? lt) + { + LtValue = lt; + return Self; + } + + /// + /// Less than or equal to. + /// + public TermsRangeQueryDescriptor Lte(string? lte) + { + LteValue = lte; + return Self; + } + + public TermsRangeQueryDescriptor QueryName(string? queryName) + { + QueryNameValue = queryName; + return Self; + } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public TermsRangeQueryDescriptor Relation(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.RangeRelation? relation) + { + RelationValue = relation; + return Self; + } + + public TermsRangeQueryDescriptor To(string? to) + { + ToValue = to; + return Self; + } + + protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + if (FieldValue is null) + throw new JsonException("Unable to serialize field name query descriptor with a null field. Ensure you use a suitable descriptor constructor or call the Field method, passing a non-null value for the field argument."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(FieldValue)); + writer.WriteStartObject(); + if (BoostValue.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(BoostValue.Value); + } + + if (!string.IsNullOrEmpty(FromValue)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(FromValue); + } + + if (!string.IsNullOrEmpty(GtValue)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(GtValue); + } + + if (!string.IsNullOrEmpty(GteValue)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(GteValue); + } + + if (!string.IsNullOrEmpty(LtValue)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(LtValue); + } + + if (!string.IsNullOrEmpty(LteValue)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(LteValue); + } + + if (!string.IsNullOrEmpty(QueryNameValue)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(QueryNameValue); + } + + if (RelationValue is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, RelationValue, options); + } + + if (!string.IsNullOrEmpty(ToValue)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(ToValue); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} \ No newline at end of file diff --git a/src/Elastic.Clients.Elasticsearch.Shared/Core/DateTime/DateMath/DateMath.cs b/src/Elastic.Clients.Elasticsearch.Shared/Core/DateTime/DateMath/DateMath.cs index 05c5217b0ad..0d8d8222168 100644 --- a/src/Elastic.Clients.Elasticsearch.Shared/Core/DateTime/DateMath/DateMath.cs +++ b/src/Elastic.Clients.Elasticsearch.Shared/Core/DateTime/DateMath/DateMath.cs @@ -20,7 +20,7 @@ namespace Elastic.Clients.Elasticsearch; public abstract class DateMath { private static readonly Regex DateMathRegex = - new(@"^(?now|.+(?:\|\||$))(?(?:(?:\+|\-)[^\/]*))?(?\/(?:y|M|w|d|h|m|s))?$"); + new(@"^(?now|.+\|\|)(?(?:(?:\+|\-)\d+(?:y|M|w|d|h|m|s))+)?(?\/(?:y|M|w|d|h|m|s))?$"); public static DateMathExpression Now => new("now"); diff --git a/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Field/Field.cs b/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Field/Field.cs index 6ecff34ef00..2b0aef9bd91 100644 --- a/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Field/Field.cs +++ b/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Field/Field.cs @@ -20,7 +20,7 @@ namespace Elastic.Clients.Elasticsearch; #endif [JsonConverter(typeof(FieldConverter))] -[DebuggerDisplay($"{nameof(DebuggerDisplay)},nq")] +[DebuggerDisplay($"{{{nameof(DebuggerDisplay)},nq}}")] public sealed class Field : IEquatable, IUrlParameter diff --git a/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Fields/Fields.cs b/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Fields/Fields.cs index 0112a9e2f2b..cf610735c72 100644 --- a/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Fields/Fields.cs +++ b/src/Elastic.Clients.Elasticsearch.Shared/Core/Infer/Fields/Fields.cs @@ -18,7 +18,7 @@ namespace Elastic.Clients.Elasticsearch.Serverless; namespace Elastic.Clients.Elasticsearch; #endif -[DebuggerDisplay($"{nameof(DebuggerDisplay)},nq")] +[DebuggerDisplay($"{{{nameof(DebuggerDisplay)},nq}}")] public sealed class Fields : IEquatable, IEnumerable, diff --git a/src/Elastic.Clients.Elasticsearch.Shared/Types/QueryDsl/RangeQuery.cs b/src/Elastic.Clients.Elasticsearch.Shared/Types/QueryDsl/RangeQuery.cs index 269e2c247eb..7a520a4d2c2 100644 --- a/src/Elastic.Clients.Elasticsearch.Shared/Types/QueryDsl/RangeQuery.cs +++ b/src/Elastic.Clients.Elasticsearch.Shared/Types/QueryDsl/RangeQuery.cs @@ -3,6 +3,9 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; #if ELASTICSEARCH_SERVERLESS using Elastic.Clients.Elasticsearch.Serverless.Fluent; @@ -88,3 +91,147 @@ public sealed partial class DateRangeQuery { public static implicit operator Query(DateRangeQuery dateRangeQuery) => Query.Range(new RangeQuery(dateRangeQuery)); } + +[JsonConverter(typeof(RangeQueryConverter))] +public sealed class RangeQuery +{ + public enum RangeQueryKind + { + Date, + Number, + Terms + } + + public RangeQueryKind Kind { get; } + public object Value { get; } + + private RangeQuery(RangeQueryKind kind, object value) + { + Kind = kind; + Value = value; + } + + public RangeQuery(DateRangeQuery date) : this(RangeQueryKind.Date, date) + { + } + + public static RangeQuery Date(DateRangeQuery date) => new(date); + + public bool IsDate => Kind is RangeQueryKind.Date; + + public bool TryGetDate([NotNullWhen(true)] out DateRangeQuery? date) + { + date = null; + if (Kind is RangeQueryKind.Date) + { + date = (DateRangeQuery)Value; + return true; + } + + return false; + } + + public static implicit operator RangeQuery(DateRangeQuery date) => Date(date); + + public RangeQuery(NumberRangeQuery number) : this(RangeQueryKind.Number, number) + { + } + + public static RangeQuery Number(NumberRangeQuery number) => new(number); + + public bool IsNumber => Kind is RangeQueryKind.Number; + + public bool TryGetNumber([NotNullWhen(true)] out NumberRangeQuery? number) + { + number = null; + if (Kind is RangeQueryKind.Number) + { + number = (NumberRangeQuery)Value; + return true; + } + + return false; + } + + public static implicit operator RangeQuery(NumberRangeQuery number) => Number(number); + + public RangeQuery(TermsRangeQuery terms) : this(RangeQueryKind.Terms, terms) + { + } + + public static RangeQuery Terms(TermsRangeQuery terms) => new(terms); + + public bool IsTerms => Kind is RangeQueryKind.Terms; + + public bool TryGetTerms([NotNullWhen(true)] out TermsRangeQuery? terms) + { + terms = null; + if (Kind is RangeQueryKind.Terms) + { + terms = (TermsRangeQuery)Value; + return true; + } + + return false; + } + + public static implicit operator RangeQuery(TermsRangeQuery terms) => Terms(terms); +} + +internal sealed class RangeQueryConverter : JsonConverter +{ + public override RangeQuery? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var readerCopy = reader; + + if (readerCopy.TokenType != JsonTokenType.StartObject) + throw new JsonException($"Unexpected token."); + + readerCopy.Read(); // Read past the opening token + readerCopy.Read(); // Read past the field name + + using var jsonDoc = JsonDocument.ParseValue(ref readerCopy); + + // When either of these properties are present, we know we have a date range query + if (jsonDoc.RootElement.TryGetProperty("format", out _) || jsonDoc.RootElement.TryGetProperty("time_zone", out _)) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + JsonElement? rangeElement = null; + + if (jsonDoc.RootElement.TryGetProperty("gte", out var gte)) + { + rangeElement = gte; + } + else if (jsonDoc.RootElement.TryGetProperty("gt", out var gt)) + { + rangeElement = gt; + } + else if (jsonDoc.RootElement.TryGetProperty("lte", out var lte)) + { + rangeElement = lte; + } + else if (jsonDoc.RootElement.TryGetProperty("lt", out var lt)) + { + rangeElement = lt; + } + + if (!rangeElement.HasValue) + { + throw new JsonException("Unable to determine type of range query."); + } + + return rangeElement.Value.ValueKind switch + { + JsonValueKind.String when DateMath.IsValidDateMathString(rangeElement.Value.GetString()!) => + JsonSerializer.Deserialize(ref reader, options), + JsonValueKind.String => JsonSerializer.Deserialize(ref reader, options), + JsonValueKind.Number => JsonSerializer.Deserialize(ref reader, options), + _ => throw new JsonException("Unsupported range query type.") + }; + } + + public override void Write(Utf8JsonWriter writer, RangeQuery value, JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, value.Value, value.Value.GetType(), options); +} diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/RangeQuery.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/RangeQuery.g.cs deleted file mode 100644 index 21533f145cd..00000000000 --- a/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/RangeQuery.g.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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. -// -// ------------------------------------------------ - -#nullable restore - -using Elastic.Clients.Elasticsearch.Core; -using Elastic.Clients.Elasticsearch.Fluent; -using Elastic.Clients.Elasticsearch.Serialization; -using Elastic.Transport; -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq.Expressions; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch.QueryDsl; - -public sealed partial class RangeQuery : Union -{ - public RangeQuery(Elastic.Clients.Elasticsearch.QueryDsl.DateRangeQuery Date) : base(Date) - { - } - - public RangeQuery(Elastic.Clients.Elasticsearch.QueryDsl.NumberRangeQuery Number) : base(Number) - { - } -} \ No newline at end of file diff --git a/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs b/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs new file mode 100644 index 00000000000..631947ba2e9 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/_Generated/Types/QueryDsl/TermsRangeQuery.g.cs @@ -0,0 +1,566 @@ +// 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. +// +// ------------------------------------------------ + +#nullable restore + +using Elastic.Clients.Elasticsearch.Fluent; +using Elastic.Clients.Elasticsearch.Serialization; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch.QueryDsl; + +internal sealed partial class TermsRangeQueryConverter : JsonConverter +{ + public override TermsRangeQuery Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Unexpected JSON detected."); + reader.Read(); + var fieldName = reader.GetString(); + reader.Read(); + var variant = new TermsRangeQuery(fieldName); + while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) + { + if (reader.TokenType == JsonTokenType.PropertyName) + { + var property = reader.GetString(); + if (property == "boost") + { + variant.Boost = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "from") + { + variant.From = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "gt") + { + variant.Gt = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "gte") + { + variant.Gte = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "lt") + { + variant.Lt = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "lte") + { + variant.Lte = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "_name") + { + variant.QueryName = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "relation") + { + variant.Relation = JsonSerializer.Deserialize(ref reader, options); + continue; + } + + if (property == "to") + { + variant.To = JsonSerializer.Deserialize(ref reader, options); + continue; + } + } + } + + reader.Read(); + return variant; + } + + public override void Write(Utf8JsonWriter writer, TermsRangeQuery value, JsonSerializerOptions options) + { + if (value.Field is null) + throw new JsonException("Unable to serialize TermsRangeQuery because the `Field` property is not set. Field name queries must include a valid field name."); + if (!options.TryGetClientSettings(out var settings)) + throw new JsonException("Unable to retrieve client settings required to infer field."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(value.Field)); + writer.WriteStartObject(); + if (value.Boost.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(value.Boost.Value); + } + + if (!string.IsNullOrEmpty(value.From)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(value.From); + } + + if (!string.IsNullOrEmpty(value.Gt)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(value.Gt); + } + + if (!string.IsNullOrEmpty(value.Gte)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(value.Gte); + } + + if (!string.IsNullOrEmpty(value.Lt)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(value.Lt); + } + + if (!string.IsNullOrEmpty(value.Lte)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(value.Lte); + } + + if (!string.IsNullOrEmpty(value.QueryName)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(value.QueryName); + } + + if (value.Relation is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, value.Relation, options); + } + + if (!string.IsNullOrEmpty(value.To)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(value.To); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} + +[JsonConverter(typeof(TermsRangeQueryConverter))] +public sealed partial class TermsRangeQuery +{ + public TermsRangeQuery(Elastic.Clients.Elasticsearch.Field field) + { + if (field is null) + throw new ArgumentNullException(nameof(field)); + Field = field; + } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public float? Boost { get; set; } + public Elastic.Clients.Elasticsearch.Field Field { get; set; } + public string? From { get; set; } + + /// + /// Greater than. + /// + public string? Gt { get; set; } + + /// + /// Greater than or equal to. + /// + public string? Gte { get; set; } + + /// + /// Less than. + /// + public string? Lt { get; set; } + + /// + /// Less than or equal to. + /// + public string? Lte { get; set; } + public string? QueryName { get; set; } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public Elastic.Clients.Elasticsearch.QueryDsl.RangeRelation? Relation { get; set; } + public string? To { get; set; } +} + +public sealed partial class TermsRangeQueryDescriptor : SerializableDescriptor> +{ + internal TermsRangeQueryDescriptor(Action> configure) => configure.Invoke(this); + + public TermsRangeQueryDescriptor() : base() + { + } + + private float? BoostValue { get; set; } + private Elastic.Clients.Elasticsearch.Field FieldValue { get; set; } + private string? FromValue { get; set; } + private string? GtValue { get; set; } + private string? GteValue { get; set; } + private string? LtValue { get; set; } + private string? LteValue { get; set; } + private string? QueryNameValue { get; set; } + private Elastic.Clients.Elasticsearch.QueryDsl.RangeRelation? RelationValue { get; set; } + private string? ToValue { get; set; } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public TermsRangeQueryDescriptor Boost(float? boost) + { + BoostValue = boost; + return Self; + } + + public TermsRangeQueryDescriptor Field(Elastic.Clients.Elasticsearch.Field field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor From(string? from) + { + FromValue = from; + return Self; + } + + /// + /// Greater than. + /// + public TermsRangeQueryDescriptor Gt(string? gt) + { + GtValue = gt; + return Self; + } + + /// + /// Greater than or equal to. + /// + public TermsRangeQueryDescriptor Gte(string? gte) + { + GteValue = gte; + return Self; + } + + /// + /// Less than. + /// + public TermsRangeQueryDescriptor Lt(string? lt) + { + LtValue = lt; + return Self; + } + + /// + /// Less than or equal to. + /// + public TermsRangeQueryDescriptor Lte(string? lte) + { + LteValue = lte; + return Self; + } + + public TermsRangeQueryDescriptor QueryName(string? queryName) + { + QueryNameValue = queryName; + return Self; + } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public TermsRangeQueryDescriptor Relation(Elastic.Clients.Elasticsearch.QueryDsl.RangeRelation? relation) + { + RelationValue = relation; + return Self; + } + + public TermsRangeQueryDescriptor To(string? to) + { + ToValue = to; + return Self; + } + + protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + if (FieldValue is null) + throw new JsonException("Unable to serialize field name query descriptor with a null field. Ensure you use a suitable descriptor constructor or call the Field method, passing a non-null value for the field argument."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(FieldValue)); + writer.WriteStartObject(); + if (BoostValue.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(BoostValue.Value); + } + + if (!string.IsNullOrEmpty(FromValue)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(FromValue); + } + + if (!string.IsNullOrEmpty(GtValue)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(GtValue); + } + + if (!string.IsNullOrEmpty(GteValue)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(GteValue); + } + + if (!string.IsNullOrEmpty(LtValue)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(LtValue); + } + + if (!string.IsNullOrEmpty(LteValue)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(LteValue); + } + + if (!string.IsNullOrEmpty(QueryNameValue)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(QueryNameValue); + } + + if (RelationValue is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, RelationValue, options); + } + + if (!string.IsNullOrEmpty(ToValue)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(ToValue); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} + +public sealed partial class TermsRangeQueryDescriptor : SerializableDescriptor +{ + internal TermsRangeQueryDescriptor(Action configure) => configure.Invoke(this); + + public TermsRangeQueryDescriptor() : base() + { + } + + private float? BoostValue { get; set; } + private Elastic.Clients.Elasticsearch.Field FieldValue { get; set; } + private string? FromValue { get; set; } + private string? GtValue { get; set; } + private string? GteValue { get; set; } + private string? LtValue { get; set; } + private string? LteValue { get; set; } + private string? QueryNameValue { get; set; } + private Elastic.Clients.Elasticsearch.QueryDsl.RangeRelation? RelationValue { get; set; } + private string? ToValue { get; set; } + + /// + /// Floating point number used to decrease or increase the relevance scores of the query.
Boost values are relative to the default value of 1.0.
A boost value between 0 and 1.0 decreases the relevance score.
A value greater than 1.0 increases the relevance score.
+ ///
+ public TermsRangeQueryDescriptor Boost(float? boost) + { + BoostValue = boost; + return Self; + } + + public TermsRangeQueryDescriptor Field(Elastic.Clients.Elasticsearch.Field field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor Field(Expression> field) + { + FieldValue = field; + return Self; + } + + public TermsRangeQueryDescriptor From(string? from) + { + FromValue = from; + return Self; + } + + /// + /// Greater than. + /// + public TermsRangeQueryDescriptor Gt(string? gt) + { + GtValue = gt; + return Self; + } + + /// + /// Greater than or equal to. + /// + public TermsRangeQueryDescriptor Gte(string? gte) + { + GteValue = gte; + return Self; + } + + /// + /// Less than. + /// + public TermsRangeQueryDescriptor Lt(string? lt) + { + LtValue = lt; + return Self; + } + + /// + /// Less than or equal to. + /// + public TermsRangeQueryDescriptor Lte(string? lte) + { + LteValue = lte; + return Self; + } + + public TermsRangeQueryDescriptor QueryName(string? queryName) + { + QueryNameValue = queryName; + return Self; + } + + /// + /// Indicates how the range query matches values for `range` fields. + /// + public TermsRangeQueryDescriptor Relation(Elastic.Clients.Elasticsearch.QueryDsl.RangeRelation? relation) + { + RelationValue = relation; + return Self; + } + + public TermsRangeQueryDescriptor To(string? to) + { + ToValue = to; + return Self; + } + + protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + if (FieldValue is null) + throw new JsonException("Unable to serialize field name query descriptor with a null field. Ensure you use a suitable descriptor constructor or call the Field method, passing a non-null value for the field argument."); + writer.WriteStartObject(); + writer.WritePropertyName(settings.Inferrer.Field(FieldValue)); + writer.WriteStartObject(); + if (BoostValue.HasValue) + { + writer.WritePropertyName("boost"); + writer.WriteNumberValue(BoostValue.Value); + } + + if (!string.IsNullOrEmpty(FromValue)) + { + writer.WritePropertyName("from"); + writer.WriteStringValue(FromValue); + } + + if (!string.IsNullOrEmpty(GtValue)) + { + writer.WritePropertyName("gt"); + writer.WriteStringValue(GtValue); + } + + if (!string.IsNullOrEmpty(GteValue)) + { + writer.WritePropertyName("gte"); + writer.WriteStringValue(GteValue); + } + + if (!string.IsNullOrEmpty(LtValue)) + { + writer.WritePropertyName("lt"); + writer.WriteStringValue(LtValue); + } + + if (!string.IsNullOrEmpty(LteValue)) + { + writer.WritePropertyName("lte"); + writer.WriteStringValue(LteValue); + } + + if (!string.IsNullOrEmpty(QueryNameValue)) + { + writer.WritePropertyName("_name"); + writer.WriteStringValue(QueryNameValue); + } + + if (RelationValue is not null) + { + writer.WritePropertyName("relation"); + JsonSerializer.Serialize(writer, RelationValue, options); + } + + if (!string.IsNullOrEmpty(ToValue)) + { + writer.WritePropertyName("to"); + writer.WriteStringValue(ToValue); + } + + writer.WriteEndObject(); + writer.WriteEndObject(); + } +} \ No newline at end of file