From cfe580f3a2ed879d90f6614b9a1dc0aa3b94806e Mon Sep 17 00:00:00 2001
From: Greg Marzouka <greg.marzouka@gmail.com>
Date: Thu, 17 Jul 2014 18:52:39 -0400
Subject: [PATCH 1/2] Fix sort mode and made accessible to all sort descriptors

---
 src/Nest/DSL/Search/SortFieldDescriptor.cs    | 38 ++++++++++++++-----
 .../DSL/Search/SortGeoDistanceDescriptor.cs   | 11 ++++++
 src/Nest/DSL/Search/SortScriptDescriptor.cs   |  9 +++++
 .../Search/Sorting/SortTests.cs               | 14 +++++--
 4 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/src/Nest/DSL/Search/SortFieldDescriptor.cs b/src/Nest/DSL/Search/SortFieldDescriptor.cs
index 50344302967..681b5cdbcfe 100644
--- a/src/Nest/DSL/Search/SortFieldDescriptor.cs
+++ b/src/Nest/DSL/Search/SortFieldDescriptor.cs
@@ -18,24 +18,36 @@ public enum SortOrder
 		Descending
 	}
 
+	[JsonConverter(typeof(StringEnumConverter))]
+	public enum SortMode
+	{
+		[EnumMember(Value = "min")]
+		Min,
+		[EnumMember(Value = "max")]
+		Max,
+		[EnumMember(Value = "sum")]
+		Sum,
+		[EnumMember(Value = "avg")]
+		Average
+	}
+
 	[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
 	public interface ISort
 	{
-
 		[JsonProperty("missing")]
 		string Missing { get; set; }
 
 		[JsonProperty("order")]
 		SortOrder? Order { get; set; }
+
+		[JsonProperty("mode")]
+		SortMode? Mode { get; set; }
 	}
 
 	public interface IFieldSort : ISort
 	{
 		PropertyPathMarker Field { get; set; }
 
-		[JsonProperty("mode")]
-		ScoreMode? Mode { get; set; }
-
 		[JsonProperty("nested_filter")]
 		FilterContainer NestedFilter { get; set; }
 
@@ -51,7 +63,7 @@ public class Sort : IFieldSort
 		public PropertyPathMarker Field { get; set; }
 		public string Missing { get; set; }
 		public SortOrder? Order { get; set; }
-		public ScoreMode? Mode { get; set; }
+		public SortMode? Mode { get; set; }
 		public FilterContainer NestedFilter { get; set; }
 		public PropertyPathMarker NestedPath { get; set; }
 		public bool? IgnoreUnmappedFields { get; set; }
@@ -67,7 +79,7 @@ public class SortFieldDescriptor<T> : IFieldSort where T : class
 
 		SortOrder? ISort.Order { get; set; }
 
-        ScoreMode? IFieldSort.Mode { get; set; }
+        SortMode? ISort.Mode { get; set; }
 
 		FilterContainer IFieldSort.NestedFilter { get; set; }
 
@@ -129,27 +141,33 @@ public virtual SortFieldDescriptor<T> Order(SortOrder order)
 			return this;
 		}
 
+		public virtual SortFieldDescriptor<T> Mode(SortMode mode)
+		{
+			Self.Mode = mode;
+			return this;
+		}
+
         public virtual SortFieldDescriptor<T> NestedMin()
         {
-            Self.Mode = ScoreMode.Min;
+            Self.Mode = SortMode.Min;
             return this;
         }
 
         public virtual SortFieldDescriptor<T> NestedMax()
         {
-			Self.Mode = ScoreMode.Max;
+			Self.Mode = SortMode.Max;
             return this;
         }
 
         public virtual SortFieldDescriptor<T> NestedSum()
         {
-            Self.Mode = ScoreMode.Sum;
+            Self.Mode = SortMode.Sum;
             return this;
         }
 
         public virtual SortFieldDescriptor<T> NestedAvg()
         {
-			Self.Mode = ScoreMode.Average;
+			Self.Mode = SortMode.Average;
             return this;
         }
 
diff --git a/src/Nest/DSL/Search/SortGeoDistanceDescriptor.cs b/src/Nest/DSL/Search/SortGeoDistanceDescriptor.cs
index 52bc93c9923..0b5925a4c45 100644
--- a/src/Nest/DSL/Search/SortGeoDistanceDescriptor.cs
+++ b/src/Nest/DSL/Search/SortGeoDistanceDescriptor.cs
@@ -20,6 +20,7 @@ public class GeoDistanceSort : IGeoDistanceSort
 	{
 		public string Missing { get; set; }
 		public SortOrder? Order { get; set; }
+		public SortMode? Mode { get; set; }
 		public PropertyPathMarker Field { get; set; }
 		public string PinLocation { get; set; }
 		public GeoUnit? GeoUnit { get; set; }
@@ -30,6 +31,7 @@ object ICustomJson.GetCustomJson()
 			{
 				{ this.Field, this.PinLocation },
 				{ "missing", this.Missing },
+				{ "mode", this.Mode },
 				{ "order", this.Order },
 				{ "unit", this.GeoUnit }
 			};
@@ -46,6 +48,8 @@ public class SortGeoDistanceDescriptor<T> : IGeoDistanceSort where T : class
 
 		SortOrder? ISort.Order { get; set; }
 
+		SortMode? ISort.Mode { get; set; }
+
 		string IGeoDistanceSort.PinLocation { get; set; }
 
 		GeoUnit? IGeoDistanceSort.GeoUnit { get; set; }
@@ -114,12 +118,19 @@ public SortGeoDistanceDescriptor<T> Order(SortOrder order)
 			return this;
 		}
 
+		public SortGeoDistanceDescriptor<T> Mode(SortMode mode)
+		{
+			Self.Mode = mode;
+			return this;
+		}
+
 		object ICustomJson.GetCustomJson()
 		{
 			return new Dictionary<object, object>
 			{
 				{ Self.Field, Self.PinLocation },
 				{ "missing", Self.Missing },
+				{ "mode", Self.Mode},
 				{ "order", Self.Order },
 				{ "unit", Self.GeoUnit }
 			};
diff --git a/src/Nest/DSL/Search/SortScriptDescriptor.cs b/src/Nest/DSL/Search/SortScriptDescriptor.cs
index 5fbb542ef17..844c94274fb 100644
--- a/src/Nest/DSL/Search/SortScriptDescriptor.cs
+++ b/src/Nest/DSL/Search/SortScriptDescriptor.cs
@@ -22,6 +22,7 @@ public class ScriptSort : IScriptSort
 	{
 		public string Missing { get; set; }
 		public SortOrder? Order { get; set; }
+		public SortMode? Mode { get; set; }
 		public string Type { get; set; }
 		public string Script { get; set; }
 		public Dictionary<string, object> Params { get; set; }
@@ -35,6 +36,8 @@ public class SortScriptDescriptor<T> : IScriptSort
 
 		SortOrder? ISort.Order { get; set; }
 
+		SortMode? ISort.Mode { get; set; }
+
 		string IScriptSort.Type { get; set; }
 
 		string IScriptSort.Script { get; set; }
@@ -97,5 +100,11 @@ public SortScriptDescriptor<T> Order(SortOrder order)
 			Self.Order = order;
 			return this;
 		}
+
+		public SortScriptDescriptor<T> Mode(SortMode mode)
+		{
+			Self.Mode = mode;
+			return this;
+		}
 	}
 }
diff --git a/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs b/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
index b2a22b34244..42c1f1d9bcc 100644
--- a/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
+++ b/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
@@ -45,6 +45,7 @@ public void TestSortOnSortField()
 					.OnField(e => e.Name.Suffix("sort"))
 					.MissingLast()
 					.Descending()
+					.Mode(SortMode.Min)
 				);
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"
@@ -54,7 +55,8 @@ public void TestSortOnSortField()
                   sort: {
                     ""name.sort"": {
                       missing: ""_last"",
-                      order: ""desc""
+                      order: ""desc"",
+					  mode: ""min""
                     }
                   }
                 }";
@@ -79,8 +81,8 @@ public void TestSortOnNestedField()
                   size: 10,
                   sort: {
                     ""contributors.age"": {
-                        ""mode"": ""max"",
-                        ""order"": ""desc""
+						""order"": ""desc"",
+                        ""mode"": ""max""
                     }
                   }
                 }";
@@ -175,6 +177,7 @@ public void TestSortGeo()
 					.Descending()
 					.PinTo(40, -70)
 					.Unit(GeoUnit.Kilometers)
+					.Mode(SortMode.Max)
 				);
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"
@@ -185,6 +188,7 @@ public void TestSortGeo()
                     _geo_distance: {
                       ""origin"": ""40, -70"",
                       missing: ""_last"",
+					  mode: ""max"",
                       order: ""desc"",
                       unit: ""km""
                     }
@@ -202,6 +206,7 @@ public void TestSortScript()
 				.SortScript(sort => sort
 					.MissingLast()
 					.Descending()
+					.Mode(SortMode.Average)
 					.Script("doc['field_name'].value * factor")
 					.Params(p => p
 						.Add("factor", 1.1)
@@ -221,7 +226,8 @@ public void TestSortScript()
                         factor: 1.1
                       },
                       missing: ""_last"",
-                      order: ""desc""
+                      order: ""desc"",
+					  mode: ""avg""
                     }
                   }
                 }";

From dbdafae66588f652b03be69d5b6c8468d47cfce0 Mon Sep 17 00:00:00 2001
From: Greg Marzouka <greg.marzouka@gmail.com>
Date: Thu, 17 Jul 2014 23:14:23 -0400
Subject: [PATCH 2/2] Serialize sorts as array instead of dictionary

---
 src/Nest/DSL/SearchDescriptor.cs              |  38 ++---
 src/Nest/Nest.csproj                          |   1 +
 .../Converters/SortCollectionConverter.cs     |  42 +++++
 .../MoreLikeThis/MoreLikeThisBody.json        |  14 +-
 .../MoreLikeThis/MoreLikeThisRequestTests.cs  |   4 +-
 .../ObjectInitializer/Search/SearchBody.json  |  14 +-
 .../Search/SearchRequestTests.cs              |   4 +-
 .../InitializerSyntax/InitializerExample.cs   |   4 +-
 .../Search/SearchOptions/SearchOptionTests.cs |  14 +-
 .../Search/Sorting/RandomScriptSort.json      |  24 +--
 .../Search/Sorting/SortTests.cs               | 150 ++++++++++--------
 11 files changed, 187 insertions(+), 122 deletions(-)
 create mode 100644 src/Nest/Resolvers/Converters/SortCollectionConverter.cs

diff --git a/src/Nest/DSL/SearchDescriptor.cs b/src/Nest/DSL/SearchDescriptor.cs
index 444a24fa7e2..eea7d97b908 100644
--- a/src/Nest/DSL/SearchDescriptor.cs
+++ b/src/Nest/DSL/SearchDescriptor.cs
@@ -41,8 +41,8 @@ public interface ISearchRequest : IQueryPath<SearchRequestParameters>
 		IDictionary<IndexNameMarker, double> IndicesBoost { get; set; }
 
 		[JsonProperty(PropertyName = "sort")]
-		[JsonConverter(typeof (DictionaryKeysAreNotPropertyNamesJsonConverter))]
-		IDictionary<PropertyPathMarker, ISort> Sort { get; set; }
+		[JsonConverter(typeof(SortCollectionConverter))]
+		IList<KeyValuePair<PropertyPathMarker, ISort>> Sort { get; set; }
 
 		[JsonProperty(PropertyName = "facets")]
 		[JsonConverter(typeof (DictionaryKeysAreNotPropertyNamesJsonConverter))]
@@ -140,7 +140,7 @@ public partial class SearchRequest : QueryPathBase<SearchRequestParameters>, ISe
 		public IList<PropertyPathMarker> Fields { get; set; }
 		public IDictionary<string, IScriptFilter> ScriptFields { get; set; }
 		public ISourceFilter Source { get; set; }
-		public IDictionary<PropertyPathMarker, ISort> Sort { get; set; }
+		public IList<KeyValuePair<PropertyPathMarker, ISort>> Sort { get; set; }
 		public IDictionary<IndexNameMarker, double> IndicesBoost { get; set; }
 		public IFilterContainer Filter { get; set; }
 		public IQueryContainer Query { get; set; }
@@ -200,7 +200,7 @@ protected override void UpdatePathInfo(IConnectionSettingsValues settings, Elast
 		public bool? TrackScores { get; set; }
 		public double? MinScore { get; set; }
 		public IDictionary<IndexNameMarker, double> IndicesBoost { get; set; }
-		public IDictionary<PropertyPathMarker, ISort> Sort { get; set; }
+		public IList<KeyValuePair<PropertyPathMarker, ISort>> Sort { get; set; }
 		public IDictionary<PropertyPathMarker, IFacetContainer> Facets { get; set; }
 		public IDictionary<string, ISuggestBucket> Suggest { get; set; }
 		public IHighlightRequest Highlight { get; set; }
@@ -290,7 +290,7 @@ string ISearchRequest.Routing
 
 		IDictionary<IndexNameMarker, double> ISearchRequest.IndicesBoost { get; set; }
 
-		IDictionary<PropertyPathMarker, ISort> ISearchRequest.Sort { get; set; }
+		IList<KeyValuePair<PropertyPathMarker, ISort>> ISearchRequest.Sort { get; set; }
 
 		IDictionary<PropertyPathMarker, IFacetContainer> ISearchRequest.Facets { get; set; }
 
@@ -568,9 +568,9 @@ public SearchDescriptor<T> ScriptFields(
 		/// </summary>
 		public SearchDescriptor<T> SortAscending(Expression<Func<T, object>> objectPath)
 		{
-			if (Self.Sort == null) Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+			if (Self.Sort == null) Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
-			Self.Sort.Add(objectPath, new Sort() { Order = SortOrder.Ascending});
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>(objectPath, new Sort() { Order = SortOrder.Ascending}));
 			return this;
 		}
 
@@ -584,9 +584,9 @@ public SearchDescriptor<T> SortAscending(Expression<Func<T, object>> objectPath)
 		/// </summary>
 		public SearchDescriptor<T> SortDescending(Expression<Func<T, object>> objectPath)
 		{
-			if (Self.Sort == null) Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+			if (Self.Sort == null) Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
-			Self.Sort.Add(objectPath, new Sort() { Order = SortOrder.Descending});
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>(objectPath, new Sort() { Order = SortOrder.Descending }));
 			return this;
 		}
 
@@ -600,8 +600,8 @@ public SearchDescriptor<T> SortDescending(Expression<Func<T, object>> objectPath
 		/// </summary>
 		public SearchDescriptor<T> SortAscending(string field)
 		{
-			if (Self.Sort == null) Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
-			Self.Sort.Add(field, new Sort() { Order = SortOrder.Ascending });
+			if (Self.Sort == null) Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>(field, new Sort() { Order = SortOrder.Ascending }));
 			return this;
 		}
 
@@ -616,9 +616,9 @@ public SearchDescriptor<T> SortAscending(string field)
 		public SearchDescriptor<T> SortDescending(string field)
 		{
 			if (Self.Sort == null)
-				Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+				Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
-			Self.Sort.Add(field, new Sort() { Order = SortOrder.Descending});
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>(field, new Sort() { Order = SortOrder.Descending}));
 			return this;
 		}
 
@@ -629,11 +629,11 @@ public SearchDescriptor<T> SortDescending(string field)
 		public SearchDescriptor<T> Sort(Func<SortFieldDescriptor<T>, IFieldSort> sortSelector)
 		{
 			if (Self.Sort == null)
-				Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+				Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
 			sortSelector.ThrowIfNull("sortSelector");
 			var descriptor = sortSelector(new SortFieldDescriptor<T>());
-			Self.Sort.Add(descriptor.Field, descriptor);
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>(descriptor.Field, descriptor));
 			return this;
 		}
 
@@ -644,11 +644,11 @@ public SearchDescriptor<T> Sort(Func<SortFieldDescriptor<T>, IFieldSort> sortSel
 		public SearchDescriptor<T> SortGeoDistance(Func<SortGeoDistanceDescriptor<T>, IGeoDistanceSort> sortSelector)
 		{
 			if (Self.Sort == null)
-				Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+				Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
 			sortSelector.ThrowIfNull("sortSelector");
 			var descriptor = sortSelector(new SortGeoDistanceDescriptor<T>());
-			Self.Sort.Add("_geo_distance", descriptor);
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>("_geo_distance", descriptor));
 			return this;
 		}
 
@@ -659,11 +659,11 @@ public SearchDescriptor<T> SortGeoDistance(Func<SortGeoDistanceDescriptor<T>, IG
 		public SearchDescriptor<T> SortScript(Func<SortScriptDescriptor<T>, IScriptSort> sortSelector)
 		{
 			if (Self.Sort == null)
-				Self.Sort = new Dictionary<PropertyPathMarker, ISort>();
+				Self.Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>();
 
 			sortSelector.ThrowIfNull("sortSelector");
 			var descriptor = sortSelector(new SortScriptDescriptor<T>());
-			Self.Sort.Add("_script", descriptor);
+			Self.Sort.Add(new KeyValuePair<PropertyPathMarker, ISort>("_script", descriptor));
 			return this;
 		}
 
diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj
index e82eee995ee..0d83b2b4b1f 100644
--- a/src/Nest/Nest.csproj
+++ b/src/Nest/Nest.csproj
@@ -791,6 +791,7 @@
     <Compile Include="Resolvers\Converters\FieldNameQueryConverter.cs" />
     <Compile Include="Resolvers\Converters\IndexSettingsResponseConverter.cs" />
     <Compile Include="Resolvers\Converters\SimilaritySettingsConverter.cs" />
+    <Compile Include="Resolvers\Converters\SortCollectionConverter.cs" />
     <Compile Include="Resolvers\Converters\SuggestResponseConverter.cs" />
     <Compile Include="Resolvers\Converters\PropertyPathMarkerConverter.cs" />
     <Compile Include="Resolvers\Converters\DynamicMappingOptionConverter.cs" />
diff --git a/src/Nest/Resolvers/Converters/SortCollectionConverter.cs b/src/Nest/Resolvers/Converters/SortCollectionConverter.cs
new file mode 100644
index 00000000000..38e1c2ee655
--- /dev/null
+++ b/src/Nest/Resolvers/Converters/SortCollectionConverter.cs
@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Nest.Resolvers.Converters
+{
+	public class SortCollectionConverter : JsonConverter
+	{
+		public override bool CanConvert(Type objectType)
+		{
+			return typeof(IList<KeyValuePair<PropertyPathMarker, ISort>>).IsAssignableFrom(objectType);
+		}
+
+		public override bool CanRead
+		{
+			get { return false; }
+		}
+
+		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+		{
+			return new InvalidOperationException();
+		}
+
+		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+		{
+			writer.WriteStartArray();
+			var sortItems = value as IList<KeyValuePair<PropertyPathMarker, ISort>>;
+			foreach (var item in sortItems)
+			{
+				writer.WriteStartObject();
+				var contract = serializer.ContractResolver as SettingsContractResolver;
+				var fieldName = contract.Infer.PropertyPath(item.Key);
+				writer.WritePropertyName(fieldName);
+				serializer.Serialize(writer, item.Value);
+				writer.WriteEndObject();
+			}
+			writer.WriteEndArray();
+		}
+	}
+}
diff --git a/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisBody.json b/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisBody.json
index 40f8fe914a4..8fe71de521c 100644
--- a/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisBody.json
+++ b/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisBody.json
@@ -1,14 +1,16 @@
- {
+{
   "from": 0,
   "size": 20,
   "explain": true,
   "track_scores": true,
-  "sort": {
-    "field": {
-      "missing": "_first",
-      "order": "asc"
+  "sort": [
+    {
+      "field": {
+        "missing": "_first",
+        "order": "asc"
+      }
     }
-  },
+  ],
   "filter": {
     "bool": {
       "must": [
diff --git a/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisRequestTests.cs b/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisRequestTests.cs
index c6c8b9568f9..71bf415c2ad 100644
--- a/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisRequestTests.cs
+++ b/src/Tests/Nest.Tests.Unit/ObjectInitializer/MoreLikeThis/MoreLikeThisRequestTests.cs
@@ -42,9 +42,9 @@ public MoreLikeThisRequestTests()
 				}),
 				TrackScores = true,
 				Explain = true,
-				Sort = new Dictionary<PropertyPathMarker, ISort>()
+				Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>()
 				{
-					{ "field", new Sort { Order = SortOrder.Ascending, Missing = "_first"}}
+					new KeyValuePair<PropertyPathMarker, ISort>("field", new Sort { Order = SortOrder.Ascending, Missing = "_first"})
 				}
 			};
 			var request = new MoreLikeThisRequest("some-index", "the-type","document-id-21")
diff --git a/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchBody.json b/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchBody.json
index 150b847da0d..0d7f55cd18c 100644
--- a/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchBody.json
+++ b/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchBody.json
@@ -1,4 +1,4 @@
-  {
+{
   "from": 0,
   "size": 20,
   "explain": true,
@@ -7,12 +7,14 @@
   "indices_boost": {
     "nest_test_data": 2.3
   },
-  "sort": {
-    "field": {
-      "missing": "_first",
-      "order": "asc"
+  "sort": [
+    {
+      "field": {
+        "missing": "_first",
+        "order": "asc"
+      }
     }
-  },
+  ],
   "facets": {
     "name": {
       "terms": {
diff --git a/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchRequestTests.cs b/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchRequestTests.cs
index 388abcaf682..6bfede02032 100644
--- a/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchRequestTests.cs
+++ b/src/Tests/Nest.Tests.Unit/ObjectInitializer/Search/SearchRequestTests.cs
@@ -39,9 +39,9 @@ public SearchRequestTests()
 				{
 					{ Infer.Index<ElasticsearchProject>(), 2.3 }
 				},
-				Sort = new Dictionary<PropertyPathMarker, ISort>()
+				Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>()
 				{
-					{ "field", new Sort { Order = SortOrder.Ascending, Missing = "_first"}}
+					new KeyValuePair<PropertyPathMarker, ISort>("field", new Sort { Order = SortOrder.Ascending, Missing = "_first"})
 				},
 				Facets = new Dictionary<PropertyPathMarker, IFacetContainer>()
 				{
diff --git a/src/Tests/Nest.Tests.Unit/Search/InitializerSyntax/InitializerExample.cs b/src/Tests/Nest.Tests.Unit/Search/InitializerSyntax/InitializerExample.cs
index a5b6d89622f..8f3c8db66ed 100644
--- a/src/Tests/Nest.Tests.Unit/Search/InitializerSyntax/InitializerExample.cs
+++ b/src/Tests/Nest.Tests.Unit/Search/InitializerSyntax/InitializerExample.cs
@@ -69,9 +69,9 @@ public void FullExample_InitializerSyntax_Search()
 							{"multiplier", 4}
 						}
 					}),
-				Sort = new Dictionary<PropertyPathMarker, ISort>()
+				Sort = new List<KeyValuePair<PropertyPathMarker, ISort>>()
 				{
-					{ "field", new Sort { Order = SortOrder.Ascending, Missing = "_first"}}
+					new KeyValuePair<PropertyPathMarker, ISort>("field", new Sort { Order = SortOrder.Ascending, Missing = "_first"})
 				},
 				Source = new SourceFilter
 				{
diff --git a/src/Tests/Nest.Tests.Unit/Search/SearchOptions/SearchOptionTests.cs b/src/Tests/Nest.Tests.Unit/Search/SearchOptions/SearchOptionTests.cs
index 54a65134f66..b123991d6f3 100644
--- a/src/Tests/Nest.Tests.Unit/Search/SearchOptions/SearchOptionTests.cs
+++ b/src/Tests/Nest.Tests.Unit/Search/SearchOptions/SearchOptionTests.cs
@@ -218,9 +218,9 @@ public void TestSort()
 				.SortAscending(e => e.LOC.Suffix("sort"));
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"{ from: 0, size: 10, 
-					sort: {
-						""loc.sort"": { order: ""asc"" }
-					},
+					sort: [
+						{""loc.sort"": { order: ""asc"" }}
+					],
 					fields: [""id"", ""name""]
 				}";
 			Assert.True(json.JsonEquals(expected), json);
@@ -236,10 +236,10 @@ public void TestSortDescending()
 				.SortDescending(e => e.Name.Suffix("sort"));
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"{ from: 0, size: 10, 
-					sort: {
-						""loc.sort"": { order: ""asc"" },
-						""name.sort"": { order: ""desc"" }
-					},
+					sort: [
+						{""loc.sort"": { order: ""asc"" }},
+						{""name.sort"": { order: ""desc"" }}
+					],
 					fields: [""id"", ""name""]
 				}";
 			Assert.True(json.JsonEquals(expected), json);
diff --git a/src/Tests/Nest.Tests.Unit/Search/Sorting/RandomScriptSort.json b/src/Tests/Nest.Tests.Unit/Search/Sorting/RandomScriptSort.json
index 1a9de1a8038..88569afcc7e 100644
--- a/src/Tests/Nest.Tests.Unit/Search/Sorting/RandomScriptSort.json
+++ b/src/Tests/Nest.Tests.Unit/Search/Sorting/RandomScriptSort.json
@@ -1,14 +1,16 @@
-  {
+{
   "from": 0,
   "size": 10,
-  "sort": {
-    "_script": {
-      "type": "number",
-      "script": "(doc['_id'].stringValue + salt).hashCode()",
-      "params": {
-        "salt": "some_random_string"
-      },
-      "order": "asc"
+  "sort": [
+    {
+      "_script": {
+        "type": "number",
+        "script": "(doc['_id'].stringValue + salt).hashCode()",
+        "params": {
+          "salt": "some_random_string"
+        },
+        "order": "asc"
+      }
     }
-  }
-}
\ No newline at end of file
+  ]
+}
diff --git a/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs b/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
index 42c1f1d9bcc..94e8051c168 100644
--- a/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
+++ b/src/Tests/Nest.Tests.Unit/Search/Sorting/SortTests.cs
@@ -24,13 +24,15 @@ public void TestSort()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    country: {
-					  ignore_unmapped: true,
-                      missing: ""_last"",
-                      order: ""desc""
+                  sort: [
+                    {
+					  country: {
+					    ignore_unmapped: true,
+                        missing: ""_last"",
+                        order: ""desc""
+					  }
                     }
-                  }
+                  ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -52,13 +54,15 @@ public void TestSortOnSortField()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    ""name.sort"": {
-                      missing: ""_last"",
-                      order: ""desc"",
-					  mode: ""min""
-                    }
-                  }
+                  sort: [
+					 {
+                      ""name.sort"": {
+                          missing: ""_last"",
+                          order: ""desc"",
+					      mode: ""min""
+                        }
+					 }
+                   ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -79,12 +83,14 @@ public void TestSortOnNestedField()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    ""contributors.age"": {
-						""order"": ""desc"",
-                        ""mode"": ""max""
-                    }
-                  }
+                  sort: [
+                    {
+					  ""contributors.age"": {
+						  ""order"": ""desc"",
+                          ""mode"": ""max"" 
+				      }
+					}
+                  ]
                 }";
             Assert.True(json.JsonEquals(expected), json);
         }
@@ -101,9 +107,9 @@ public void TestSortAscending()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    country : { order: ""asc"" }
-                    }          
+                  sort: [
+					  { country : { order: ""asc"" } }
+                    ]      
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -120,9 +126,9 @@ public void TestSortDescending()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    country : { order: ""desc"" }
-                    }          
+                  sort: [
+                      { country : { order: ""desc"" } }
+                    ]      
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -139,9 +145,9 @@ public void TestSortAscendingOnSortField()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    ""name.sort"" : { order: ""asc"" }
-                    }          
+                  sort: [
+                      {""name.sort"" : { order: ""asc"" } }
+                    ]      
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -158,9 +164,9 @@ public void TestSortDescendingOnSortField()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    ""name.sort"" : { order: ""desc"" }
-                    }          
+                  sort: [
+                      { ""name.sort"" : { order: ""desc"" } }
+                    ]      
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -184,15 +190,17 @@ public void TestSortGeo()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    _geo_distance: {
-                      ""origin"": ""40, -70"",
-                      missing: ""_last"",
-					  mode: ""max"",
-                      order: ""desc"",
-                      unit: ""km""
-                    }
-                  }
+                  sort: [
+					{
+					  _geo_distance: {
+					   ""origin"": ""40, -70"",
+						 missing: ""_last"",
+						 mode: ""max"",
+						 order: ""desc"",
+						 unit: ""km""
+					  }
+					}
+                  ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -218,18 +226,20 @@ public void TestSortScript()
                 {
                   from: 0,
                   size: 10,
-                  sort: {
-                    _script: {
-                      type: ""number"",
-                      script: ""doc['field_name'].value * factor"",
-                      params: {
-                        factor: 1.1
-                      },
-                      missing: ""_last"",
-                      order: ""desc"",
-					  mode: ""avg""
-                    }
-                  }
+                  sort: [
+					{
+                      _script: {
+                        type: ""number"",
+                        script: ""doc['field_name'].value * factor"",
+                        params: {
+                          factor: 1.1
+                        },
+                        missing: ""_last"",
+                        order: ""desc"",
+					    mode: ""avg""
+                      }
+					}
+                  ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -245,16 +255,18 @@ public void TestNestedFilter()
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"
                 {
-                  ""sort"": {
-                    ""id"": {
+                ""sort"": [
+                    {
+					""id"": {
                       ""nested_filter"": {
                         ""term"": {
                           ""name"": ""value""
+                          }
                         }
                       }
-                    }
-                  }
-                }";
+				    }
+                   ]
+                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
 
@@ -269,11 +281,13 @@ public void TestNestedPath()
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"
                 {
-                  ""sort"": {
-                    ""id"": {
-                      ""nested_path"": ""name""
-                    }
-                  }
+                  ""sort"": [
+                    {
+					  ""id"": {
+					    ""nested_path"": ""name""
+					  }
+					}
+                  ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}
@@ -289,11 +303,13 @@ public void TestNestedPathObject()
 			var json = TestElasticClient.Serialize(s);
 			var expected = @"
                 {
-                  ""sort"": {
-                    ""id"": {
-                      ""nested_path"": ""name""
-                    }
-                  }
+                  ""sort"": [
+                    {
+					  ""id"": {
+						""nested_path"": ""name""
+					  }
+					}
+                  ]
                 }";
 			Assert.True(json.JsonEquals(expected), json);
 		}