From a72268ee8c326edce1a6a6aed3ee4bd727219d95 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Mon, 16 Feb 2015 12:37:35 +0100 Subject: [PATCH 1/3] fix #1274 add support for precision and orientation on geo shape type mapping --- .../Descriptors/GeoShapeMappingDescriptor.cs | 12 +++++++++ .../Domain/Mapping/Types/GeoShapeMapping.cs | 6 +++++ src/Nest/Enums/GeoOrientation.cs | 15 +++++++++++ src/Nest/Enums/GeoPrecision.cs | 25 +++++++++++++++++++ src/Nest/Nest.csproj | 2 ++ 5 files changed, 60 insertions(+) create mode 100644 src/Nest/Enums/GeoOrientation.cs create mode 100644 src/Nest/Enums/GeoPrecision.cs diff --git a/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs index 51087c70ade..552147991c4 100644 --- a/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs @@ -30,6 +30,18 @@ public GeoShapeMappingDescriptor TreeLevels(int treeLevels) return this; } + public GeoShapeMappingDescriptor Precision(GeoPrecision precision) + { + this._Mapping.Precision = precision; + return this; + } + + public GeoShapeMappingDescriptor Orientation(GeoOrientation orientation) + { + this._Mapping.Orientation = orientation; + return this; + } + public GeoShapeMappingDescriptor DistanceErrorPercentage(double distanceErrorPercentage) { this._Mapping.DistanceErrorPercentage = distanceErrorPercentage; diff --git a/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs b/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs index bbaef372d6b..2e7d3074613 100644 --- a/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs +++ b/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs @@ -19,6 +19,12 @@ public class GeoShapeMapping : IElasticType [JsonProperty("tree"), JsonConverter(typeof(StringEnumConverter))] public GeoTree? Tree { get; set; } + [JsonProperty("precision")] + public GeoPrecision? Precision { get; set; } + + [JsonProperty("orientation")] + public GeoOrientation? Orientation { get; set; } + [JsonProperty("tree_levels")] public int? TreeLevels { get; set; } diff --git a/src/Nest/Enums/GeoOrientation.cs b/src/Nest/Enums/GeoOrientation.cs new file mode 100644 index 00000000000..249cab5fe95 --- /dev/null +++ b/src/Nest/Enums/GeoOrientation.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Nest +{ + [JsonConverter(typeof(StringEnumConverter))] + public enum GeoOrientation + { + [EnumMember(Value = "cw")] + ClockWise, + [EnumMember(Value = "ccw")] + CounterClockWise + } +} diff --git a/src/Nest/Enums/GeoPrecision.cs b/src/Nest/Enums/GeoPrecision.cs new file mode 100644 index 00000000000..abf39ab96b0 --- /dev/null +++ b/src/Nest/Enums/GeoPrecision.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Nest +{ + [JsonConverter(typeof(StringEnumConverter))] + public enum GeoPrecision + { + [EnumMember(Value = "in")] + Inch, + [EnumMember(Value = "yd")] + Yard, + [EnumMember(Value = "mi")] + Miles, + [EnumMember(Value = "km")] + Kilometers, + [EnumMember(Value = "m")] + Meters, + [EnumMember(Value = "cm")] + Centimeters, + [EnumMember(Value = "mm")] + Millimeters + } +} diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index d44dde07e69..d59e82603a7 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -242,6 +242,8 @@ + + From b71bbad36df5a49f1dcdaaf2b92471071e5451f0 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Tue, 17 Feb 2015 15:04:23 +0100 Subject: [PATCH 2/3] Strongly typed geo precision as combination of double and unit and wrote a converter for it with tests --- src/Nest/Domain/Geo/GeoPrecision.cs | 22 ++++++++ .../Descriptors/GeoShapeMappingDescriptor.cs | 4 +- .../Descriptors/MappingTransformDescriptor.cs | 10 ++-- .../Domain/Mapping/Types/GeoShapeMapping.cs | 2 +- src/Nest/Enums/GeoPrecisionUnit.cs | 25 +++++++++ src/Nest/Nest.csproj | 4 +- .../Converters/GeoPrecisionConverter.cs | 52 +++++++++++++++++++ .../Core/Map/GeoShape/GeoShapeMappingTests.cs | 48 +++++++++++++++++ .../GeoShape/PrecisionSerializesAsString.json | 11 ++++ .../Nest.Tests.Unit/Nest.Tests.Unit.csproj | 4 ++ 10 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 src/Nest/Domain/Geo/GeoPrecision.cs create mode 100644 src/Nest/Enums/GeoPrecisionUnit.cs create mode 100644 src/Nest/Resolvers/Converters/GeoPrecisionConverter.cs create mode 100644 src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/GeoShapeMappingTests.cs create mode 100644 src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/PrecisionSerializesAsString.json diff --git a/src/Nest/Domain/Geo/GeoPrecision.cs b/src/Nest/Domain/Geo/GeoPrecision.cs new file mode 100644 index 00000000000..7aae452a7f0 --- /dev/null +++ b/src/Nest/Domain/Geo/GeoPrecision.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Nest.Resolvers.Converters; + +namespace Nest +{ + [JsonConverter(typeof(GeoPrecisionConverter))] + public class GeoPrecision + { + public double Precision { get; private set; } + public GeoPrecisionUnit Unit { get; private set; } + + public GeoPrecision(double precision, GeoPrecisionUnit unit) + { + this.Precision = precision; + this.Unit = unit; + } + } +} diff --git a/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs index 552147991c4..d1f2ea9186c 100644 --- a/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/GeoShapeMappingDescriptor.cs @@ -30,9 +30,9 @@ public GeoShapeMappingDescriptor TreeLevels(int treeLevels) return this; } - public GeoShapeMappingDescriptor Precision(GeoPrecision precision) + public GeoShapeMappingDescriptor Precision(double precision, GeoPrecisionUnit unit) { - this._Mapping.Precision = precision; + this._Mapping.Precision = new GeoPrecision(precision, unit); return this; } diff --git a/src/Nest/Domain/Mapping/Descriptors/MappingTransformDescriptor.cs b/src/Nest/Domain/Mapping/Descriptors/MappingTransformDescriptor.cs index b4a482a00b9..3d3bc3964a4 100644 --- a/src/Nest/Domain/Mapping/Descriptors/MappingTransformDescriptor.cs +++ b/src/Nest/Domain/Mapping/Descriptors/MappingTransformDescriptor.cs @@ -28,10 +28,10 @@ public MappingTransformDescriptor Language(string language) return this; } - public MappingTransformDescriptor Language(ScriptLang language) - { - this._mappingTransform.Language = language.GetStringValue(); - return this; - } + public MappingTransformDescriptor Language(ScriptLang language) + { + this._mappingTransform.Language = language.GetStringValue(); + return this; + } } } diff --git a/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs b/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs index 2e7d3074613..7ff763e4151 100644 --- a/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs +++ b/src/Nest/Domain/Mapping/Types/GeoShapeMapping.cs @@ -20,7 +20,7 @@ public class GeoShapeMapping : IElasticType public GeoTree? Tree { get; set; } [JsonProperty("precision")] - public GeoPrecision? Precision { get; set; } + public GeoPrecision Precision { get; set; } [JsonProperty("orientation")] public GeoOrientation? Orientation { get; set; } diff --git a/src/Nest/Enums/GeoPrecisionUnit.cs b/src/Nest/Enums/GeoPrecisionUnit.cs new file mode 100644 index 00000000000..6b6916e5350 --- /dev/null +++ b/src/Nest/Enums/GeoPrecisionUnit.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Nest +{ + [JsonConverter(typeof(StringEnumConverter))] + public enum GeoPrecisionUnit + { + [EnumMember(Value = "in")] + Inch, + [EnumMember(Value = "yd")] + Yard, + [EnumMember(Value = "mi")] + Miles, + [EnumMember(Value = "km")] + Kilometers, + [EnumMember(Value = "m")] + Meters, + [EnumMember(Value = "cm")] + Centimeters, + [EnumMember(Value = "mm")] + Millimeters + } +} diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index d59e82603a7..b35c92d145f 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -130,6 +130,7 @@ + @@ -243,7 +244,7 @@ - + @@ -984,6 +985,7 @@ + diff --git a/src/Nest/Resolvers/Converters/GeoPrecisionConverter.cs b/src/Nest/Resolvers/Converters/GeoPrecisionConverter.cs new file mode 100644 index 00000000000..2028c5ee49b --- /dev/null +++ b/src/Nest/Resolvers/Converters/GeoPrecisionConverter.cs @@ -0,0 +1,52 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.IO; +using System.Text.RegularExpressions; + +namespace Nest.Resolvers.Converters +{ + public class GeoPrecisionConverter : JsonConverter + { + private static readonly Regex SplitRegex = new Regex(@"^(\d+(?:[.,]\d+)?)(\D+)$"); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var p = value as GeoPrecision; + if (p == null) + { + writer.WriteNull(); + return; + } + using (var sw = new StringWriter()) + using (var localWriter = new JsonTextWriter(sw)) + { + serializer.Serialize(localWriter, p.Precision); + localWriter.WriteRaw(p.Unit.GetStringValue()); + var s = sw.ToString(); + writer.WriteValue(s); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.String) return null; + var v = reader.Value as string; + if (v == null) return null; + var matches = SplitRegex.Matches(v); + if (matches.Count < 0 + || matches[0].Groups.Count < 3) + return null; + double p; + var sp = matches[0].Groups[1].Captures[0].Value; + if (!double.TryParse(sp, out p)) return null; + var unit = matches[0].Groups[2].Captures[0].Value.ToEnum(); + if (!unit.HasValue) return null; + return new GeoPrecision(p, unit.Value); + } + + public override bool CanConvert(Type objectType) + { + return true; + } + } +} \ No newline at end of file diff --git a/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/GeoShapeMappingTests.cs b/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/GeoShapeMappingTests.cs new file mode 100644 index 00000000000..486ef8c456a --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/GeoShapeMappingTests.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Elasticsearch.Net; +using FluentAssertions; +using Nest.Resolvers; +using Nest.Tests.MockData.Domain; +using NUnit.Framework; + +namespace Nest.Tests.Unit.Core.Map.GeoShape +{ + [TestFixture] + public class GeoShapeMappingTests : BaseJsonTests + { + + [Test] + public void PrecisionSerializesAsString() + { + var result = this._client.Map(m => m + .Properties(props => props + .GeoShape(s => s + .Name(p => p.MyGeoShape) + .Precision(1.2, GeoPrecisionUnit.Centimeters) + .DistanceErrorPercentage(0.025) + ) + ) + ); + this.JsonEquals(result.ConnectionStatus.Request, MethodInfo.GetCurrentMethod()); + } + + [Test] + public void PrecisionSurvivesDeserialize() + { + var mapping = new GeoShapeMapping() + { + Name = Property.Name(p => p.MyGeoShape), + Precision = new GeoPrecision(3.4, GeoPrecisionUnit.Yard) + }; + var serialized = this._client.Serializer.Serialize(mapping); + var deserialized = this._client.Serializer.Deserialize(new MemoryStream(serialized)); + deserialized.Should().NotBeNull(); + deserialized.Precision.Should().NotBeNull(); + deserialized.Precision.Precision.Should().Be(3.4); + deserialized.Precision.Unit.Should().Be(GeoPrecisionUnit.Yard); + + } + } +} diff --git a/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/PrecisionSerializesAsString.json b/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/PrecisionSerializesAsString.json new file mode 100644 index 00000000000..aa5dfab58c9 --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Core/Map/GeoShape/PrecisionSerializesAsString.json @@ -0,0 +1,11 @@ +{ + "elasticsearchprojects": { + "properties": { + "myGeoShape": { + "type": "geo_shape", + "precision": "1.2cm", + "distance_error_pct": 0.025 + } + } + } +} diff --git a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj index 3350a8033df..a0bcc448c16 100644 --- a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj +++ b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj @@ -108,6 +108,7 @@ + @@ -178,6 +179,9 @@ Always + + Always + Always From 8d3822ff49ef12bcdc501efb8c2b01dc24fe0faf Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Tue, 17 Feb 2015 15:23:00 +0100 Subject: [PATCH 3/3] csproj file changes --- src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj index a0bcc448c16..4cebdc8499a 100644 --- a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj +++ b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj @@ -108,7 +108,7 @@ - + @@ -179,7 +179,7 @@ Always - + Always