Skip to content

[Backport 8.1] Add support for geo_bounding_box query. #7330

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
Mar 14, 2023
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
1 change: 0 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ resharper_redundant_case_label_highlighting=do_not_show
resharper_redundant_argument_default_value_highlighting=do_not_show

spelling_languages=en-us,en-gb
spelling_exclusion_path=.\exclusion.dic

[Jenkinsfile]
indent_style = space
Expand Down
3 changes: 2 additions & 1 deletion exclusion.dic
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ async
inferrer
elasticsearch
asciidocs
yyyy
yyyy
enum
13 changes: 13 additions & 0 deletions src/Elastic.Clients.Elasticsearch/Core/IComplexUnion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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;

namespace Elastic.Clients.Elasticsearch.Core;

internal interface IComplexUnion<TEnum> where TEnum : Enum
{
internal TEnum ValueKind { get; }
internal object Value { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// 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;
using Elastic.Clients.Elasticsearch.Core;

namespace Elastic.Clients.Elasticsearch.Serialization;

/// <summary>
/// A base converter for any multi-item (>2 items) unions. The code-generator creates a
/// derived type which populates the fields in its constructor.
/// IMPORTANT: This is a MVP implementation which meets the requirements for the currently
/// generated multi-item unions. Additional logic may be needed when we first encounter
/// other item types. In the interests of time, we are not covering all cases for now.
/// </summary>
internal abstract class MultiItemUnionConverter<TUnion, TEnum> : JsonConverter<TUnion>
where TUnion : IComplexUnion<TEnum>
where TEnum : Enum
{
// Used when serializing to specify the type for each enum kind.
protected Dictionary<TEnum, Type> _types;

// Used when creating an instance of the TUnion for a specific type.
protected Dictionary<Type, Func<object, TUnion>> _factories;

// Used when deserializing objects, to determine which type we have.
protected Dictionary<string, Type> _uniquePropertyToType;

protected Type _arrayType; // For now, we handle only unions with one item being defined as an array

public override TUnion? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
const string exceptionMessage = "Unable to match JSON object to union item.";

// Plan of attack!!
// - If the token is start object:
// - For types which are objects, we need to identify required properties
// - Determine if each object has a unique required property (if not we need to find unique combinations)
// - If none are unique, we may struggle, but we can also check for unique optional properties
// - If the token is a literal value, see if we have a matching literal available
// - If the token is the start of an array, do we have an array type identified (we currently only support one array-based item).

if (_factories is null)
ThrowHelper.ThrowJsonException("No factories have been registered for deserialization.");

// We'll be handling an object
if (reader.TokenType == JsonTokenType.StartObject)
{
var readerCopy = reader; // We need a copy to use when reading ahead

if (_uniquePropertyToType is null)
ThrowHelper.ThrowJsonException(exceptionMessage);

using var jsonDoc = JsonDocument.ParseValue(ref readerCopy);

if (jsonDoc is null)
ThrowHelper.ThrowJsonException(exceptionMessage);

Type? matchedType = null;

// Loop through the unique properties of each possible object.
// Once we find a match we can stop checking any further.
foreach (var item in _uniquePropertyToType)
{
if (jsonDoc.RootElement.TryGetProperty(item.Key, out _))
{
// We've matched a unique property in the JSON object, so now know the type
matchedType = item.Value;
break;
}
}

if (matchedType is null)
ThrowHelper.ThrowJsonException(exceptionMessage);

if (!_factories.TryGetValue(matchedType, out var factory))
ThrowHelper.ThrowJsonException("Unable to locate factory for multi-item union object item.");

// Since we now know the type and have the factory for that type, we can deserialize the object
// and pass it to the factory to create the instance.

var value = JsonSerializer.Deserialize(ref reader, matchedType, options);

return factory.Invoke(value);
}

if (reader.TokenType == JsonTokenType.String)
{
var value = reader.GetString();
reader.Read();

if (!_factories.TryGetValue(typeof(string), out var factory))
ThrowHelper.ThrowJsonException("Unable to locate factory for multi-item union accepting a string value.");

return factory.Invoke(value);
}

if (reader.TokenType == JsonTokenType.StartArray)
{
if (_arrayType is null)
ThrowHelper.ThrowJsonException(exceptionMessage);

if (!_factories.TryGetValue(_arrayType, out var factory))
ThrowHelper.ThrowJsonException("Unable to locate factory for multi-item union accepting an array value.");

var value = JsonSerializer.Deserialize(ref reader, _arrayType, options);

return factory.Invoke(value);
}

ThrowHelper.ThrowJsonException($"Unable to deserialize JSON representing {typeof(TUnion)}.");

return default; // We never reach here!
}

public override void Write(Utf8JsonWriter writer, TUnion value, JsonSerializerOptions options)
{
if (_types is null)
ThrowHelper.ThrowJsonException("No types have been registered for serialization.");

if (value is null)
{
writer.WriteNullValue();
return;
}

var serializeAsType = _types[value.ValueKind];

JsonSerializer.Serialize(writer, value.Value, serializeAsType, options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// 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.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;

#nullable restore
namespace Elastic.Clients.Elasticsearch;
public sealed partial class CoordsGeoBounds
{
[JsonInclude, JsonPropertyName("bottom")]
public double Bottom { get; set; }

[JsonInclude, JsonPropertyName("left")]
public double Left { get; set; }

[JsonInclude, JsonPropertyName("right")]
public double Right { get; set; }

[JsonInclude, JsonPropertyName("top")]
public double Top { get; set; }
}

public sealed partial class CoordsGeoBoundsDescriptor : SerializableDescriptor<CoordsGeoBoundsDescriptor>
{
internal CoordsGeoBoundsDescriptor(Action<CoordsGeoBoundsDescriptor> configure) => configure.Invoke(this);
public CoordsGeoBoundsDescriptor() : base()
{
}

private double BottomValue { get; set; }

private double LeftValue { get; set; }

private double RightValue { get; set; }

private double TopValue { get; set; }

public CoordsGeoBoundsDescriptor Bottom(double bottom)
{
BottomValue = bottom;
return Self;
}

public CoordsGeoBoundsDescriptor Left(double left)
{
LeftValue = left;
return Self;
}

public CoordsGeoBoundsDescriptor Right(double right)
{
RightValue = right;
return Self;
}

public CoordsGeoBoundsDescriptor Top(double top)
{
TopValue = top;
return Self;
}

protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
{
writer.WriteStartObject();
writer.WritePropertyName("bottom");
writer.WriteNumberValue(BottomValue);
writer.WritePropertyName("left");
writer.WriteNumberValue(LeftValue);
writer.WritePropertyName("right");
writer.WriteNumberValue(RightValue);
writer.WritePropertyName("top");
writer.WriteNumberValue(TopValue);
writer.WriteEndObject();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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.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;

#nullable restore
namespace Elastic.Clients.Elasticsearch.Core.Search;
public sealed partial class Context : Union<string, Elastic.Clients.Elasticsearch.GeoLocation>
{
public Context(string category) : base(category)
{
}

public Context(Elastic.Clients.Elasticsearch.GeoLocation location) : base(location)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand Down
Loading