From 83cd7a6f58167812741eb3484562389cb2fca753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Thu, 11 Sep 2014 19:05:17 +0200 Subject: [PATCH 1/6] Updated Match query to take different Fuzziness --- src/Nest/DSL/Query/MatchQueryDescriptor.cs | 23 +++- .../Queries/MatchQueryJsonConverter.cs | 13 +- .../QueryParsers/Queries/MatchQueryTests.cs | 130 ++++++++++++++++-- .../Search/Query/Singles/MatchQueryJson.cs | 1 - 4 files changed, 147 insertions(+), 20 deletions(-) diff --git a/src/Nest/DSL/Query/MatchQueryDescriptor.cs b/src/Nest/DSL/Query/MatchQueryDescriptor.cs index 0553da6a289..726cdb0e2b6 100644 --- a/src/Nest/DSL/Query/MatchQueryDescriptor.cs +++ b/src/Nest/DSL/Query/MatchQueryDescriptor.cs @@ -27,7 +27,7 @@ public interface IMatchQuery : IFieldNameQuery RewriteMultiTerm? Rewrite { get; set; } [JsonProperty(PropertyName = "fuzziness")] - double? Fuzziness { get; set; } + IFuzziness Fuzziness { get; set; } [JsonProperty(PropertyName = "cutoff_frequency")] double? CutoffFrequency { get; set; } @@ -79,7 +79,7 @@ void IFieldNameQuery.SetFieldName(string fieldName) public string Query { get; set; } public string Analyzer { get; set; } public RewriteMultiTerm? Rewrite { get; set; } - public double? Fuzziness { get; set; } + public IFuzziness Fuzziness { get; set; } public double? CutoffFrequency { get; set; } public int? PrefixLength { get; set; } public int? MaxExpansions { get; set; } @@ -109,7 +109,7 @@ public class MatchQueryDescriptor : IMatchQuery where T : class RewriteMultiTerm? IMatchQuery.Rewrite { get; set; } - double? IMatchQuery.Fuzziness { get; set; } + IFuzziness IMatchQuery.Fuzziness { get; set; } double? IMatchQuery.CutoffFrequency { get; set; } @@ -172,10 +172,21 @@ public MatchQueryDescriptor Analyzer(string analyzer) Self.Analyzer = analyzer; return this; } - - public MatchQueryDescriptor Fuzziness(double fuzziness) + + public MatchQueryDescriptor Fuzziness(double ratio) + { + Self.Fuzziness = Nest.Fuzziness.Ratio(ratio); + return this; + } + public MatchQueryDescriptor Fuzziness() + { + Self.Fuzziness = Nest.Fuzziness.Auto; + return this; + } + + public MatchQueryDescriptor Fuzziness(int editDistance) { - Self.Fuzziness = fuzziness; + Self.Fuzziness = Nest.Fuzziness.EditDistance(editDistance); return this; } diff --git a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs index 96dead1b771..c3e3a5a9a83 100644 --- a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs +++ b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs @@ -44,7 +44,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist fq.Boost = GetPropValue(jo, "boost"); fq.Analyzer = GetPropValue(jo, "analyzer"); fq.CutoffFrequency = GetPropValue(jo, "cutoff_frequency"); - fq.Fuzziness = GetPropValue(jo, "fuzziness"); + fq.Fuzziness = GetFuzzinessValue(jo); fq.Lenient = GetPropValue(jo, "lenient"); fq.MaxExpansions = GetPropValue(jo, "max_expansions"); fq.PrefixLength = GetPropValue(jo, "prefix_length"); @@ -62,6 +62,17 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } + private IFuzziness GetFuzzinessValue(JObject jObject) + { + JToken jToken; + + if (!jObject.TryGetValue("fuzziness", out jToken)) return null; + if (jToken.Type == JTokenType.Float) return Fuzziness.Ratio(jToken.Value()); + if (jToken.Type == JTokenType.Integer) return Fuzziness.EditDistance(jToken.Value()); + + return Fuzziness.Auto; + } + public TReturn GetPropValue(JObject jObject, string propertyName) { JToken jToken = null; diff --git a/src/Tests/Nest.Tests.Unit/QueryParsers/Queries/MatchQueryTests.cs b/src/Tests/Nest.Tests.Unit/QueryParsers/Queries/MatchQueryTests.cs index c98369b8944..9b8c51c919d 100644 --- a/src/Tests/Nest.Tests.Unit/QueryParsers/Queries/MatchQueryTests.cs +++ b/src/Tests/Nest.Tests.Unit/QueryParsers/Queries/MatchQueryTests.cs @@ -10,9 +10,9 @@ public class MatchQueryTests : ParseQueryTestsBase public void Match_Deserializes() { var q = this.SerializeThenDeserialize( - f=>f.Match, - f=>f.Match(m=>m - .OnField(p=>p.Name) + f => f.Match, + f => f.Match(m => m + .OnField(p => p.Name) .Analyzer("my-analyzer") .Boost(2.1) .CutoffFrequency(1.31) @@ -31,7 +31,113 @@ public void Match_Deserializes() q.Analyzer.Should().Be("my-analyzer"); q.Boost.Should().Be(2.1); q.CutoffFrequency.Should().Be(1.31); - q.Fuzziness.Should().Be(2.3); + q.Fuzziness.Ratio.Should().Be(2.3); + q.Lenient.Should().BeTrue(); + q.MaxExpansions.Should().Be(2); + q.Field.Should().Be("name"); + q.Operator.Should().Be(Operator.And); + q.PrefixLength.Should().Be(2); + q.Query.Should().Be("querytext"); + q.Rewrite.Should().Be(RewriteMultiTerm.ConstantScoreBoolean); + q.Slop.Should().Be(2); + } + + [Test] + public void Match_DeserializesWithFuzzinessEditDistance() + { + var q = this.SerializeThenDeserialize( + f => f.Match, + f => f.Match(m => m + .OnField(p => p.Name) + .Analyzer("my-analyzer") + .Boost(2.1) + .CutoffFrequency(1.31) + .Fuzziness(2) + .Lenient() + .MaxExpansions(2) + .Operator(Operator.And) + .PrefixLength(2) + .Query("querytext") + .Rewrite(RewriteMultiTerm.ConstantScoreBoolean) + .Slop(2) + ) + ); + + q.Type.Should().Be(null); + q.Analyzer.Should().Be("my-analyzer"); + q.Boost.Should().Be(2.1); + q.CutoffFrequency.Should().Be(1.31); + q.Fuzziness.EditDistance.Should().Be(2); + q.Lenient.Should().BeTrue(); + q.MaxExpansions.Should().Be(2); + q.Field.Should().Be("name"); + q.Operator.Should().Be(Operator.And); + q.PrefixLength.Should().Be(2); + q.Query.Should().Be("querytext"); + q.Rewrite.Should().Be(RewriteMultiTerm.ConstantScoreBoolean); + q.Slop.Should().Be(2); + } + + [Test] + public void Match_DeserializesWithoutFuzziness() + { + var q = this.SerializeThenDeserialize( + f => f.Match, + f => f.Match(m => m + .OnField(p => p.Name) + .Analyzer("my-analyzer") + .Boost(2.1) + .CutoffFrequency(1.31) + .Lenient() + .MaxExpansions(2) + .Operator(Operator.And) + .PrefixLength(2) + .Query("querytext") + .Rewrite(RewriteMultiTerm.ConstantScoreBoolean) + .Slop(2) + ) + ); + + q.Type.Should().Be(null); + q.Analyzer.Should().Be("my-analyzer"); + q.Boost.Should().Be(2.1); + q.CutoffFrequency.Should().Be(1.31); + q.Lenient.Should().BeTrue(); + q.MaxExpansions.Should().Be(2); + q.Field.Should().Be("name"); + q.Operator.Should().Be(Operator.And); + q.PrefixLength.Should().Be(2); + q.Query.Should().Be("querytext"); + q.Rewrite.Should().Be(RewriteMultiTerm.ConstantScoreBoolean); + q.Slop.Should().Be(2); + } + + [Test] + public void Match_DeserializesWithFuzzinessAuto() + { + var q = this.SerializeThenDeserialize( + f => f.Match, + f => f.Match(m => m + .OnField(p => p.Name) + .Analyzer("my-analyzer") + .Boost(2.1) + .CutoffFrequency(1.31) + .Fuzziness() + .Lenient() + .MaxExpansions(2) + .Operator(Operator.And) + .PrefixLength(2) + .Query("querytext") + .Rewrite(RewriteMultiTerm.ConstantScoreBoolean) + .Slop(2) + ) + ); + + q.Type.Should().Be(null); + q.Analyzer.Should().Be("my-analyzer"); + q.Boost.Should().Be(2.1); + q.CutoffFrequency.Should().Be(1.31); + q.Fuzziness.Auto.Should().BeTrue(); q.Lenient.Should().BeTrue(); q.MaxExpansions.Should().Be(2); q.Field.Should().Be("name"); @@ -46,9 +152,9 @@ public void Match_Deserializes() public void MatchPhrasePhrefix_Deserializes() { var q = this.SerializeThenDeserialize( - f=>f.Match, - f=>f.MatchPhrasePrefix(m=>m - .OnField(p=>p.Name) + f => f.Match, + f => f.MatchPhrasePrefix(m => m + .OnField(p => p.Name) .Analyzer("my-analyzer") .Boost(2.1) .CutoffFrequency(1.31) @@ -66,7 +172,7 @@ public void MatchPhrasePhrefix_Deserializes() q.Analyzer.Should().Be("my-analyzer"); q.Boost.Should().Be(2.1); q.CutoffFrequency.Should().Be(1.31); - q.Fuzziness.Should().Be(2.3); + q.Fuzziness.Ratio.Should().Be(2.3); q.Lenient.Should().BeTrue(); q.MaxExpansions.Should().Be(2); q.Field.Should().Be("name"); @@ -81,9 +187,9 @@ public void MatchPhrasePhrefix_Deserializes() public void MatchPhrase_Deserializes() { var q = this.SerializeThenDeserialize( - f=>f.Match, - f=>f.MatchPhrase(m=>m - .OnField(p=>p.Name) + f => f.Match, + f => f.MatchPhrase(m => m + .OnField(p => p.Name) .Analyzer("my-analyzer") .Boost(2.1) .CutoffFrequency(1.31) @@ -101,7 +207,7 @@ public void MatchPhrase_Deserializes() q.Analyzer.Should().Be("my-analyzer"); q.Boost.Should().Be(2.1); q.CutoffFrequency.Should().Be(1.31); - q.Fuzziness.Should().Be(2.3); + q.Fuzziness.Ratio.Should().Be(2.3); q.Lenient.Should().BeTrue(); q.MaxExpansions.Should().Be(2); q.Field.Should().Be("name"); diff --git a/src/Tests/Nest.Tests.Unit/Search/Query/Singles/MatchQueryJson.cs b/src/Tests/Nest.Tests.Unit/Search/Query/Singles/MatchQueryJson.cs index 8e41f9ee7ea..8b038cd70a0 100644 --- a/src/Tests/Nest.Tests.Unit/Search/Query/Singles/MatchQueryJson.cs +++ b/src/Tests/Nest.Tests.Unit/Search/Query/Singles/MatchQueryJson.cs @@ -74,7 +74,6 @@ public void MatchQuerySomeOptions() .Match(t => t .OnField(f => f.Name) .Query("this is a test") - .Fuzziness(1.0) .Analyzer("my_analyzer") .CutoffFrequency(0.3) From 0bcd009f0ed676ac10a9cfa9f17942634dab10e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Thu, 11 Sep 2014 19:24:06 +0200 Subject: [PATCH 2/6] Minor tweaks to the GetFuzzinessValue method A tad more explicit. --- .../Resolvers/Converters/Queries/MatchQueryJsonConverter.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs index c3e3a5a9a83..d0679a614b4 100644 --- a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs +++ b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Nest.DSL.Query.Behaviour; using Nest.Resolvers; @@ -62,15 +63,16 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } - private IFuzziness GetFuzzinessValue(JObject jObject) + private static IFuzziness GetFuzzinessValue(IDictionary jObject) { JToken jToken; if (!jObject.TryGetValue("fuzziness", out jToken)) return null; + if (jToken.Type == JTokenType.String) return Fuzziness.Auto; if (jToken.Type == JTokenType.Float) return Fuzziness.Ratio(jToken.Value()); if (jToken.Type == JTokenType.Integer) return Fuzziness.EditDistance(jToken.Value()); - return Fuzziness.Auto; + return null; } public TReturn GetPropValue(JObject jObject, string propertyName) From be636ade11dfe6ce9a8c91f3245b844dd466b539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Mon, 15 Sep 2014 20:48:42 +0200 Subject: [PATCH 3/6] Small refactor in BaseParserTests That I didn't need after all, but I left in :) --- .../QueryParsers/BaseParserTests.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Tests/Nest.Tests.Unit/QueryParsers/BaseParserTests.cs b/src/Tests/Nest.Tests.Unit/QueryParsers/BaseParserTests.cs index 31f8269d5be..4502627f591 100644 --- a/src/Tests/Nest.Tests.Unit/QueryParsers/BaseParserTests.cs +++ b/src/Tests/Nest.Tests.Unit/QueryParsers/BaseParserTests.cs @@ -13,18 +13,15 @@ public abstract class BaseParserTests : BaseJsonTests { public ISearchRequest GetSearchDescriptorForQuery(Func, SearchDescriptor> create) { - var descriptor = create(new SearchDescriptor()); - var json = this._client.Serializer.Serialize(descriptor); - Console.WriteLine(json.Utf8String()); - using (var ms = new MemoryStream(json)) - { - ISearchRequest d = this._client.Serializer.Deserialize>(ms); - d.Should().NotBeNull(); - d.Query.Should().NotBeNull(); - return d; - } + return GetSearchDescriptor(create, request => request.Query.Should().NotBeNull()); } + public ISearchRequest GetSearchDescriptorForFilter(Func, SearchDescriptor> create) + { + return GetSearchDescriptor(create, request => request.Filter.Should().NotBeNull()); + } + + private ISearchRequest GetSearchDescriptor(Func, SearchDescriptor> create, Action assertFunc ) { var descriptor = create(new SearchDescriptor()); var json = this._client.Serializer.Serialize(descriptor); @@ -33,7 +30,7 @@ public ISearchRequest GetSearchDescriptorForFilter(Func>(ms); d.Should().NotBeNull(); - d.Filter.Should().NotBeNull(); + assertFunc(d); return d; } } From 845e93e5df9a870bfa0b7484678707cbf07b5163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Mon, 15 Sep 2014 20:52:32 +0200 Subject: [PATCH 4/6] Fuzziness converter logic FuzzinessConverterHelper All logic in ```FuzzinessConverterHelper.ReadJson()``` Tests that exercise both the ```FuzzinessConverter``` and ```MatchQueryJsonConverter``` to test ```FuzzinessConverterHelper``` --- src/Nest/Nest.csproj | 1 + .../Converters/FuzzinessConverter.cs | 19 ++--- .../Helpers/FuzzinessConverterHelper.cs | 20 +++++ .../Queries/MatchQueryJsonConverter.cs | 15 +--- .../Converters/BaseConverterTest.cs | 40 +++++++++ .../Converters/FuzzinessConverterTests.cs | 85 +++++++++++++++++++ .../Nest.Tests.Unit/Nest.Tests.Unit.csproj | 2 + 7 files changed, 154 insertions(+), 28 deletions(-) create mode 100644 src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs create mode 100644 src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs create mode 100644 src/Tests/Nest.Tests.Unit/Converters/FuzzinessConverterTests.cs diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index 50213d86174..3c678f6cad4 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -803,6 +803,7 @@ + diff --git a/src/Nest/Resolvers/Converters/FuzzinessConverter.cs b/src/Nest/Resolvers/Converters/FuzzinessConverter.cs index 50fa1d3bd9a..73fb8a303c6 100644 --- a/src/Nest/Resolvers/Converters/FuzzinessConverter.cs +++ b/src/Nest/Resolvers/Converters/FuzzinessConverter.cs @@ -1,10 +1,10 @@ using System; using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Nest.Resolvers.Converters { - public class FuzzinessConverter : JsonConverter { public override bool CanWrite { get { return true; } } @@ -22,19 +22,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (reader.TokenType == JsonToken.String) - return Fuzziness.Auto; - if (reader.TokenType == JsonToken.Integer) - { - var editDistance = (reader.Value as int?).GetValueOrDefault(0); - return Fuzziness.EditDistance(editDistance); - } - if (reader.TokenType == JsonToken.Float) - { - var ratio = (reader.Value as double?).GetValueOrDefault(0); - return Fuzziness.Ratio(ratio); - } - return null; + if (reader.TokenType == JsonToken.None) return null; + + var jsonPath = reader.Path.Split('.').Last(); + return FuzzinessConverterHelper.ReadJson(new JObject(new JProperty(jsonPath, reader.Value))); } public override bool CanConvert(Type objectType) diff --git a/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs b/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs new file mode 100644 index 00000000000..1042fb4ada5 --- /dev/null +++ b/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using Newtonsoft.Json.Linq; + +namespace Nest +{ + public static class FuzzinessConverterHelper + { + public static IFuzziness ReadJson(IDictionary jObject) + { + JToken jToken; + + if (!jObject.TryGetValue("fuzziness", out jToken)) return null; + if (jToken.Type == JTokenType.String) return Fuzziness.Auto; + if (jToken.Type == JTokenType.Float) return Fuzziness.Ratio(jToken.Value()); + if (jToken.Type == JTokenType.Integer) return Fuzziness.EditDistance(jToken.Value()); + + return null; + } + } +} \ No newline at end of file diff --git a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs index d0679a614b4..fbfc1521216 100644 --- a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs +++ b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using Nest.DSL.Query.Behaviour; using Nest.Resolvers; @@ -45,7 +44,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist fq.Boost = GetPropValue(jo, "boost"); fq.Analyzer = GetPropValue(jo, "analyzer"); fq.CutoffFrequency = GetPropValue(jo, "cutoff_frequency"); - fq.Fuzziness = GetFuzzinessValue(jo); + fq.Fuzziness = FuzzinessConverterHelper.ReadJson(jo); fq.Lenient = GetPropValue(jo, "lenient"); fq.MaxExpansions = GetPropValue(jo, "max_expansions"); fq.PrefixLength = GetPropValue(jo, "prefix_length"); @@ -63,18 +62,6 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } - private static IFuzziness GetFuzzinessValue(IDictionary jObject) - { - JToken jToken; - - if (!jObject.TryGetValue("fuzziness", out jToken)) return null; - if (jToken.Type == JTokenType.String) return Fuzziness.Auto; - if (jToken.Type == JTokenType.Float) return Fuzziness.Ratio(jToken.Value()); - if (jToken.Type == JTokenType.Integer) return Fuzziness.EditDistance(jToken.Value()); - - return null; - } - public TReturn GetPropValue(JObject jObject, string propertyName) { JToken jToken = null; diff --git a/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs b/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs new file mode 100644 index 00000000000..1e13de71747 --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs @@ -0,0 +1,40 @@ +using System.Globalization; +using System.IO; +using System.Threading; +using Elasticsearch.Net.Connection; + +namespace Nest.Tests.Unit.Converters +{ + public abstract class BaseConverterTest + { + protected IElasticClient Client; + + protected BaseConverterTest() + { + Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us"); + IConnectionSettingsValues settings = new ConnectionSettings(UnitTestDefaults.Uri, UnitTestDefaults.DefaultIndex) + .DisablePing() + .ExposeRawResponse(); + + var connection = new InMemoryConnection(settings); + + Client = new ElasticClient(settings, connection); + } + + protected T SerializeAndDeserialize(T expected) + { + var json = Client.Serializer.Serialize(expected); + + using (var ms = new MemoryStream(json)) + { + return Client.Serializer.Deserialize(ms); + } + } + + protected class ConverterTestObject + { + public string Name { get; set; } + public IFuzziness Fuzziness { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Tests/Nest.Tests.Unit/Converters/FuzzinessConverterTests.cs b/src/Tests/Nest.Tests.Unit/Converters/FuzzinessConverterTests.cs new file mode 100644 index 00000000000..7d755aa5c62 --- /dev/null +++ b/src/Tests/Nest.Tests.Unit/Converters/FuzzinessConverterTests.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using FluentAssertions; +using Nest.Tests.MockData.Domain; +using NUnit.Framework; + +namespace Nest.Tests.Unit.Converters +{ + [TestFixture] + public class FuzzinessConverterTests : BaseConverterTest + { + [Test] + public void ItCanConvertMatchFuzziness() + { + var expected = new QueryDescriptor().Match(m => m + .OnField("myfield") + .Query("myquery") + .Fuzziness()); + + var actual = SerializeAndDeserialize(expected); + + actual.Match.Fuzziness.EditDistance.Should().Be(null); + actual.Match.Fuzziness.Ratio.Should().Be(null); + actual.Match.Fuzziness.Auto.Should().BeTrue(); + } + + [Test] + public void ItCanConvertMatchFuzzinessEditDistance() + { + var expected = new QueryDescriptor().Match(m => m + .OnField("myfield") + .Query("myquery") + .Fuzziness(2)); + + var actual = SerializeAndDeserialize(expected); + + actual.Match.Fuzziness.EditDistance.Should().Be(2); + actual.Match.Fuzziness.Ratio.Should().Be(null); + actual.Match.Fuzziness.Auto.Should().BeFalse(); + } + + [Test] + public void ItCanConvertMatchFuzzinessRatio() + { + var expected = new QueryDescriptor().Match(m => m + .OnField("myfield") + .Query("myquery") + .Fuzziness(1.3)); + + var actual = SerializeAndDeserialize(expected); + + actual.Match.Fuzziness.EditDistance.Should().Be(null); + actual.Match.Fuzziness.Ratio.Should().Be(1.3); + actual.Match.Fuzziness.Auto.Should().BeFalse(); + } + + [Test] + public void ItCanConvertFuzziness() + { + var expectedObjects = new List + { + new ConverterTestObject + { + Name = "FuzzinessTest", + Fuzziness = Fuzziness.Auto + }, + new ConverterTestObject + { + Name = "FuzzinessTest", + Fuzziness = Fuzziness.EditDistance(2) + }, + new ConverterTestObject + { + Name = "FuzzinessTest", + Fuzziness = Fuzziness.Ratio(23.21123) + } + }; + + var actual = SerializeAndDeserialize(expectedObjects); + + actual[0].Fuzziness.Auto.Should().BeTrue(); + actual[1].Fuzziness.EditDistance.Should().Be(2); + actual[2].Fuzziness.Ratio.Should().Be(23.21123); + } + } +} \ No newline at end of file diff --git a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj index d87502b49e3..c42dfffd813 100644 --- a/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj +++ b/src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj @@ -121,6 +121,8 @@ + + From 2b000d0d9df5a08c487b51a4312333572a50b84a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Tue, 16 Sep 2014 16:46:04 +0200 Subject: [PATCH 5/6] Updated BaseConverterTest to inherit BaseJonTests --- .../Converters/BaseConverterTest.cs | 25 +++---------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs b/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs index 1e13de71747..f84e0bd8162 100644 --- a/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs +++ b/src/Tests/Nest.Tests.Unit/Converters/BaseConverterTest.cs @@ -1,33 +1,16 @@ -using System.Globalization; -using System.IO; -using System.Threading; -using Elasticsearch.Net.Connection; +using System.IO; namespace Nest.Tests.Unit.Converters { - public abstract class BaseConverterTest + public abstract class BaseConverterTest : BaseJsonTests { - protected IElasticClient Client; - - protected BaseConverterTest() - { - Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-us"); - IConnectionSettingsValues settings = new ConnectionSettings(UnitTestDefaults.Uri, UnitTestDefaults.DefaultIndex) - .DisablePing() - .ExposeRawResponse(); - - var connection = new InMemoryConnection(settings); - - Client = new ElasticClient(settings, connection); - } - protected T SerializeAndDeserialize(T expected) { - var json = Client.Serializer.Serialize(expected); + var json = _client.Serializer.Serialize(expected); using (var ms = new MemoryStream(json)) { - return Client.Serializer.Deserialize(ms); + return _client.Serializer.Deserialize(ms); } } From 323e0fd75034601570f705b04c59280581a15322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=98sthus?= Date: Tue, 16 Sep 2014 17:07:52 +0200 Subject: [PATCH 6/6] Made the MatchQueryJsonConverter use the FuzzinessConverter Now the MatchQueryJsonConverter uses the FuzzinessConverter to deserialize IFuzziness. This removes the ugly object creation in FuzzinessConverter to get the object into a unified format. --- src/Nest/Nest.csproj | 1 - .../Converters/FuzzinessConverter.cs | 17 ++++++++++++---- .../Helpers/FuzzinessConverterHelper.cs | 20 ------------------- .../Queries/MatchQueryJsonConverter.cs | 12 ++++++++++- 4 files changed, 24 insertions(+), 26 deletions(-) delete mode 100644 src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index 3c678f6cad4..50213d86174 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -803,7 +803,6 @@ - diff --git a/src/Nest/Resolvers/Converters/FuzzinessConverter.cs b/src/Nest/Resolvers/Converters/FuzzinessConverter.cs index 73fb8a303c6..f5d14cec998 100644 --- a/src/Nest/Resolvers/Converters/FuzzinessConverter.cs +++ b/src/Nest/Resolvers/Converters/FuzzinessConverter.cs @@ -22,10 +22,19 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (reader.TokenType == JsonToken.None) return null; - - var jsonPath = reader.Path.Split('.').Last(); - return FuzzinessConverterHelper.ReadJson(new JObject(new JProperty(jsonPath, reader.Value))); + if (reader.TokenType == JsonToken.String) + return Fuzziness.Auto; + if (reader.TokenType == JsonToken.Integer) + { + var editDistance = Convert.ToInt32(reader.Value); + return Fuzziness.EditDistance(editDistance); + } + if (reader.TokenType == JsonToken.Float) + { + var ratio = (reader.Value as double?).GetValueOrDefault(0); + return Fuzziness.Ratio(ratio); + } + return null; } public override bool CanConvert(Type objectType) diff --git a/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs b/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs deleted file mode 100644 index 1042fb4ada5..00000000000 --- a/src/Nest/Resolvers/Converters/Helpers/FuzzinessConverterHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json.Linq; - -namespace Nest -{ - public static class FuzzinessConverterHelper - { - public static IFuzziness ReadJson(IDictionary jObject) - { - JToken jToken; - - if (!jObject.TryGetValue("fuzziness", out jToken)) return null; - if (jToken.Type == JTokenType.String) return Fuzziness.Auto; - if (jToken.Type == JTokenType.Float) return Fuzziness.Ratio(jToken.Value()); - if (jToken.Type == JTokenType.Integer) return Fuzziness.EditDistance(jToken.Value()); - - return null; - } - } -} \ No newline at end of file diff --git a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs index fbfc1521216..e913cd60923 100644 --- a/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs +++ b/src/Nest/Resolvers/Converters/Queries/MatchQueryJsonConverter.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using Nest.DSL.Query.Behaviour; using Nest.Resolvers; @@ -44,7 +45,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist fq.Boost = GetPropValue(jo, "boost"); fq.Analyzer = GetPropValue(jo, "analyzer"); fq.CutoffFrequency = GetPropValue(jo, "cutoff_frequency"); - fq.Fuzziness = FuzzinessConverterHelper.ReadJson(jo); + fq.Fuzziness = GetFuzziness(jo); fq.Lenient = GetPropValue(jo, "lenient"); fq.MaxExpansions = GetPropValue(jo, "max_expansions"); fq.PrefixLength = GetPropValue(jo, "prefix_length"); @@ -62,6 +63,15 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return fq; } + private static IFuzziness GetFuzziness(IDictionary jObject) + { + JToken jToken; + if (!jObject.TryGetValue("fuzziness", out jToken)) return null; + + var tmp = jToken.ToObject(); + return tmp; + } + public TReturn GetPropValue(JObject jObject, string propertyName) { JToken jToken = null;