Browse Source

Remove support for sorting terms aggregation by ascending count

closes #17614
Jim Ferenczi 9 years ago
parent
commit
755721953b

+ 3 - 16
core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/InternalOrder.java

@@ -46,9 +46,8 @@ import java.util.Objects;
 class InternalOrder extends Terms.Order {
 
     private static final byte COUNT_DESC_ID = 1;
-    private static final byte COUNT_ASC_ID = 2;
-    private static final byte TERM_DESC_ID = 3;
-    private static final byte TERM_ASC_ID = 4;
+    private static final byte TERM_DESC_ID = 2;
+    private static final byte TERM_ASC_ID = 3;
 
     /**
      * Order by the (higher) count of each term.
@@ -60,17 +59,6 @@ class InternalOrder extends Terms.Order {
         }
     });
 
-    /**
-     * Order by the (lower) count of each term.
-     */
-    public static final InternalOrder COUNT_ASC = new InternalOrder(COUNT_ASC_ID, "_count", true, new Comparator<Terms.Bucket>() {
-
-        @Override
-        public int compare(Terms.Bucket o1, Terms.Bucket o2) {
-            return Long.compare(o1.getDocCount(), o2.getDocCount());
-        }
-    });
-
     /**
      * Order by the terms.
      */
@@ -93,7 +81,7 @@ class InternalOrder extends Terms.Order {
         }
     });
 
-    public static boolean isCountDesc(Terms.Order order) {
+    public static boolean isCountOrder(Terms.Order order) {
         if (order == COUNT_DESC) {
             return true;
         } else if (order instanceof CompoundOrder) {
@@ -348,7 +336,6 @@ class InternalOrder extends Terms.Order {
             byte id = in.readByte();
             switch (id) {
                 case COUNT_DESC_ID: return absoluteOrder ? new CompoundOrder(Collections.singletonList((Terms.Order) InternalOrder.COUNT_DESC)) : InternalOrder.COUNT_DESC;
-                case COUNT_ASC_ID: return absoluteOrder ? new CompoundOrder(Collections.singletonList((Terms.Order) InternalOrder.COUNT_ASC)) : InternalOrder.COUNT_ASC;
                 case TERM_DESC_ID: return InternalOrder.TERM_DESC;
                 case TERM_ASC_ID: return InternalOrder.TERM_ASC;
                 case Aggregation.ID:

+ 1 - 1
core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/InternalTerms.java

@@ -192,7 +192,7 @@ public abstract class InternalTerms<A extends InternalTerms, B extends InternalT
             final long thisAggDocCountError;
             if (terms.buckets.size() < this.shardSize || InternalOrder.isTermOrder(order)) {
                 thisAggDocCountError = 0;
-            } else if (InternalOrder.isCountDesc(this.order)) {
+            } else if (InternalOrder.isCountOrder(this.order)) {
                 thisAggDocCountError = terms.buckets.get(terms.buckets.size() - 1).docCount;
             } else {
                 thisAggDocCountError = -1;

+ 3 - 3
core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/Terms.java

@@ -100,10 +100,10 @@ public interface Terms extends MultiBucketsAggregation {
     static abstract class Order implements ToXContent {
 
         /**
-         * @return a bucket ordering strategy that sorts buckets by their document counts (ascending or descending)
+         * @return a bucket ordering strategy that sorts buckets by their document counts (descending)
          */
-        public static Order count(boolean asc) {
-            return asc ? InternalOrder.COUNT_ASC : InternalOrder.COUNT_DESC;
+        public static Order count() {
+            return InternalOrder.COUNT_DESC;
         }
 
         /**

+ 1 - 1
core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java

@@ -53,7 +53,7 @@ public class TermsAggregationBuilder extends ValuesSourceAggregationBuilder<Valu
     public static final ParseField SHOW_TERM_DOC_COUNT_ERROR = new ParseField("show_term_doc_count_error");
     public static final ParseField ORDER_FIELD = new ParseField("order");
 
-    private Terms.Order order = Terms.Order.compound(Terms.Order.count(false), Terms.Order.term(true));
+    private Terms.Order order = Terms.Order.compound(Terms.Order.count(), Terms.Order.term(true));
     private IncludeExclude includeExclude = null;
     private String executionHint = null;
     private SubAggCollectionMode collectMode = null;

+ 17 - 3
core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsParser.java

@@ -77,9 +77,19 @@ public class TermsParser extends AbstractTermsParser {
     @Override
     public boolean parseSpecial(String aggregationName, XContentParser parser, ParseFieldMatcher parseFieldMatcher, Token token,
             String currentFieldName, Map<ParseField, Object> otherOptions) throws IOException {
-        if (token == XContentParser.Token.START_OBJECT) {
+        if (token == Token.VALUE_STRING) {
             if (parseFieldMatcher.match(currentFieldName, TermsAggregationBuilder.ORDER_FIELD)) {
-                otherOptions.put(TermsAggregationBuilder.ORDER_FIELD, Collections.singletonList(parseOrderParam(aggregationName, parser)));
+                if ("_count".equals(parser.text())) {
+                    otherOptions.put(TermsAggregationBuilder.ORDER_FIELD,
+                        Collections.singletonList(new OrderElement(parser.text(), false)));
+                    return true;
+                }
+            }
+            return false;
+        } else if (token == XContentParser.Token.START_OBJECT) {
+            if (parseFieldMatcher.match(currentFieldName, TermsAggregationBuilder.ORDER_FIELD)) {
+                otherOptions.put(TermsAggregationBuilder.ORDER_FIELD,
+                    Collections.singletonList(parseOrderParam(aggregationName, parser)));
                 return true;
             }
         } else if (token == XContentParser.Token.START_ARRAY) {
@@ -117,6 +127,10 @@ public class TermsParser extends AbstractTermsParser {
             } else if (token == XContentParser.Token.VALUE_STRING) {
                 String dir = parser.text();
                 if ("asc".equalsIgnoreCase(dir)) {
+                    if ("_count".equals(orderKey)) {
+                        throw new ParsingException(parser.getTokenLocation(),
+                            "Sort by ascending _count is not supported in [" + aggregationName + "].");
+                    }
                     orderAsc = true;
                 } else if ("desc".equalsIgnoreCase(dir)) {
                     orderAsc = false;
@@ -167,7 +181,7 @@ public class TermsParser extends AbstractTermsParser {
             return Order.term(asc);
         }
         if ("_count".equals(key)) {
-            return Order.count(asc);
+            return Order.count();
         }
         return Order.aggregation(key, asc);
     }

+ 12 - 12
core/src/test/java/org/elasticsearch/search/aggregations/bucket/ShardSizeTermsIT.java

@@ -39,7 +39,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms  terms = response.getAggregations().get("keys");
@@ -62,7 +62,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3).shardSize(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms  terms = response.getAggregations().get("keys");
@@ -86,7 +86,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -110,7 +110,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type").setRouting(routing1)
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -156,7 +156,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -179,7 +179,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3).shardSize(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -202,7 +202,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -226,7 +226,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type").setRouting(routing1)
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -272,7 +272,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -295,7 +295,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3).shardSize(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -318,7 +318,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type")
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");
@@ -341,7 +341,7 @@ public class ShardSizeTermsIT extends ShardSizeTestCase {
         SearchResponse response = client().prepareSearch("idx").setTypes("type").setRouting(routing1)
                 .setQuery(matchAllQuery())
                 .addAggregation(terms("keys").field("key").size(3)
-                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count(false)))
+                        .collectMode(randomFrom(SubAggCollectionMode.values())).shardSize(5).order(Terms.Order.count()))
                 .execute().actionGet();
 
         Terms terms = response.getAggregations().get("keys");

+ 0 - 93
core/src/test/java/org/elasticsearch/search/aggregations/bucket/TermsDocCountErrorIT.java

@@ -271,37 +271,6 @@ public class TermsDocCountErrorIT extends ESIntegTestCase {
         assertNoDocCountErrorSingleResponse(size, testResponse);
     }
 
-    public void testStringValueFieldDocCountAsc() throws Exception {
-        int size = randomIntBetween(1, 20);
-        int shardSize = randomIntBetween(size, size * 2);
-        SearchResponse accurateResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(STRING_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(10000).shardSize(10000)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(accurateResponse);
-
-        SearchResponse testResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(STRING_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(size)
-                        .shardSize(shardSize)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(testResponse);
-
-        assertUnboundedDocCountError(size, accurateResponse, testResponse);
-    }
-
     public void testStringValueFieldTermSortAsc() throws Exception {
         int size = randomIntBetween(1, 20);
         int shardSize = randomIntBetween(size, size * 2);
@@ -507,37 +476,6 @@ public class TermsDocCountErrorIT extends ESIntegTestCase {
         assertNoDocCountErrorSingleResponse(size, testResponse);
     }
 
-    public void testLongValueFieldDocCountAsc() throws Exception {
-        int size = randomIntBetween(1, 20);
-        int shardSize = randomIntBetween(size, size * 2);
-        SearchResponse accurateResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(LONG_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(10000).shardSize(10000)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(accurateResponse);
-
-        SearchResponse testResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(LONG_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(size)
-                        .shardSize(shardSize)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(testResponse);
-
-        assertUnboundedDocCountError(size, accurateResponse, testResponse);
-    }
-
     public void testLongValueFieldTermSortAsc() throws Exception {
         int size = randomIntBetween(1, 20);
         int shardSize = randomIntBetween(size, size * 2);
@@ -743,37 +681,6 @@ public class TermsDocCountErrorIT extends ESIntegTestCase {
         assertNoDocCountErrorSingleResponse(size, testResponse);
     }
 
-    public void testDoubleValueFieldDocCountAsc() throws Exception {
-        int size = randomIntBetween(1, 20);
-        int shardSize = randomIntBetween(size, size * 2);
-        SearchResponse accurateResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(DOUBLE_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(10000).shardSize(10000)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(accurateResponse);
-
-        SearchResponse testResponse = client().prepareSearch("idx_single_shard").setTypes("type")
-                .addAggregation(terms("terms")
-                        .executionHint(randomExecutionHint())
-                        .field(DOUBLE_FIELD_NAME)
-                        .showTermDocCountError(true)
-                        .size(size)
-                        .shardSize(shardSize)
-                        .order(Order.count(true))
-                        .collectMode(randomFrom(SubAggCollectionMode.values())))
-                .execute().actionGet();
-
-        assertSearchResponse(testResponse);
-
-        assertUnboundedDocCountError(size, accurateResponse, testResponse);
-    }
-
     public void testDoubleValueFieldTermSortAsc() throws Exception {
         int size = randomIntBetween(1, 20);
         int shardSize = randomIntBetween(size, size * 2);

+ 1 - 1
core/src/test/java/org/elasticsearch/search/aggregations/bucket/TermsTests.java

@@ -180,7 +180,7 @@ public class TermsTests extends BaseAggregationTestCase<TermsAggregationBuilder>
             orders.add(Terms.Order.term(randomBoolean()));
             break;
         case 1:
-            orders.add(Terms.Order.count(randomBoolean()));
+            orders.add(Terms.Order.count());
             break;
         case 2:
             orders.add(Terms.Order.aggregation(randomAsciiOfLengthBetween(3, 20), randomBoolean()));

+ 8 - 5
docs/reference/aggregations/bucket/terms-aggregation.asciidoc

@@ -239,9 +239,7 @@ determined and is given a value of -1 to indicate this.
 ==== Order
 
 The order of the buckets can be customized by setting the `order` parameter. By default, the buckets are ordered by
-their `doc_count` descending. It is also possible to change this behaviour as follows:
-
-Ordering the buckets by their `doc_count` in an ascending manner:
+their `doc_count` descending:
 
 [source,js]
 --------------------------------------------------
@@ -250,12 +248,15 @@ Ordering the buckets by their `doc_count` in an ascending manner:
         "genders" : {
             "terms" : {
                 "field" : "gender",
-                "order" : { "_count" : "asc" }
+                "order" : "_count" <1>
             }
         }
     }
 }
 --------------------------------------------------
+<1> This is the default if the order is missing.
+
+It is also possible to change this behaviour as follows:
 
 Ordering the buckets alphabetically by their terms in an ascending manner:
 
@@ -312,7 +313,9 @@ Ordering the buckets by multi value metrics sub-aggregation (identified by the a
 }
 --------------------------------------------------
 
-WARNING: Sorting by ascending `_count` or by sub aggregation is discouraged as it increases the
+Ordering the buckets by their `doc_count` in an ascending manner is not supported.
+
+WARNING: Sorting by sub aggregation is discouraged as it increases the
 <<search-aggregations-bucket-terms-aggregation-approximate-counts,error>> on document counts.
 It is fine when a single shard is queried, or when the field that is being aggregated was used
 as a routing key at index time: in these cases results will be accurate since shards have disjoint

+ 4 - 0
docs/reference/migration/migrate_5_0/aggregations.asciidoc

@@ -26,3 +26,7 @@ for `from` and `to` anymore.
 `size: 0` is no longer valid for the terms, significant terms and geohash grid
 aggregations. Instead a size should be explicitly specified with a number greater
 than zero.
+
+==== `order: {"count": "asc"}` on Terms
+
+The ability to sort the terms aggregation by ascending count has been removed.

+ 1 - 6
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/DoubleTermsTests.java

@@ -1048,11 +1048,6 @@ public class DoubleTermsTests extends AbstractTermsTestCase {
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("avg_l", false), Terms.Order.term(true));
     }
 
-    public void testSingleValuedFieldOrderedByCountAscAndSingleValueSubAggregationAsc() throws Exception {
-        double[] expectedKeys = new double[] { 6, 7, 3, 4, 5, 1, 2 };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(true), Terms.Order.aggregation("avg_l", true));
-    }
-
     public void testSingleValuedFieldOrderedBySingleValueSubAggregationAscSingleValueSubAggregationAsc() throws Exception {
         double[] expectedKeys = new double[] { 6, 7, 3, 5, 4, 1, 2 };
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("sum_d", true), Terms.Order.aggregation("avg_l", true));
@@ -1060,7 +1055,7 @@ public class DoubleTermsTests extends AbstractTermsTestCase {
 
     public void testSingleValuedFieldOrderedByThreeCriteria() throws Exception {
         double[] expectedKeys = new double[] { 2, 1, 4, 5, 3, 6, 7 };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(false), Terms.Order.aggregation("sum_d", false), Terms.Order.aggregation("avg_l", false));
+        assertMultiSortResponse(expectedKeys, Terms.Order.count(), Terms.Order.aggregation("sum_d", false), Terms.Order.aggregation("avg_l", false));
     }
 
     public void testSingleValuedFieldOrderedBySingleValueSubAggregationAscAsCompound() throws Exception {

+ 1 - 6
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/LongTermsTests.java

@@ -1025,11 +1025,6 @@ public class LongTermsTests extends AbstractTermsTestCase {
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("avg_l", false), Terms.Order.term(true));
     }
 
-    public void testSingleValuedFieldOrderedByCountAscAndSingleValueSubAggregationAsc() throws Exception {
-        long[] expectedKeys = new long[] { 6, 7, 3, 4, 5, 1, 2 };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(true), Terms.Order.aggregation("avg_l", true));
-    }
-
     public void testSingleValuedFieldOrderedBySingleValueSubAggregationAscSingleValueSubAggregationAsc() throws Exception {
         long[] expectedKeys = new long[] { 6, 7, 3, 5, 4, 1, 2 };
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("sum_d", true), Terms.Order.aggregation("avg_l", true));
@@ -1037,7 +1032,7 @@ public class LongTermsTests extends AbstractTermsTestCase {
 
     public void testSingleValuedFieldOrderedByThreeCriteria() throws Exception {
         long[] expectedKeys = new long[] { 2, 1, 4, 5, 3, 6, 7 };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(false), Terms.Order.aggregation("sum_d", false), Terms.Order.aggregation("avg_l", false));
+        assertMultiSortResponse(expectedKeys, Terms.Order.count(), Terms.Order.aggregation("sum_d", false), Terms.Order.aggregation("avg_l", false));
     }
 
     public void testSingleValuedFieldOrderedBySingleValueSubAggregationAscAsCompound() throws Exception {

+ 8 - 40
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/MinDocCountTests.java

@@ -173,36 +173,20 @@ public class MinDocCountTests extends AbstractTermsTestCase {
         testMinDocCountOnTerms("s", Script.YES, Terms.Order.term(false));
     }
 
-    public void testStringCountAsc() throws Exception {
-        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count(true));
-    }
-
-    public void testStringScriptCountAsc() throws Exception {
-        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count(true));
-    }
-
     public void testStringCountDesc() throws Exception {
-        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count(false));
+        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count());
     }
 
     public void testStringScriptCountDesc() throws Exception {
-        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count(false));
-    }
-
-    public void testStringCountAscWithInclude() throws Exception {
-        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count(true), ".*a.*", true);
-    }
-
-    public void testStringScriptCountAscWithInclude() throws Exception {
-        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count(true), ".*a.*", true);
+        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count());
     }
 
     public void testStringCountDescWithInclude() throws Exception {
-        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count(false), ".*a.*", true);
+        testMinDocCountOnTerms("s", Script.NO, Terms.Order.count(), ".*a.*", true);
     }
 
     public void testStringScriptCountDescWithInclude() throws Exception {
-        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count(false), ".*a.*", true);
+        testMinDocCountOnTerms("s", Script.YES, Terms.Order.count(), ".*a.*", true);
     }
 
     public void testLongTermAsc() throws Exception {
@@ -221,20 +205,12 @@ public class MinDocCountTests extends AbstractTermsTestCase {
         testMinDocCountOnTerms("l", Script.YES, Terms.Order.term(false));
     }
 
-    public void testLongCountAsc() throws Exception {
-        testMinDocCountOnTerms("l", Script.NO, Terms.Order.count(true));
-    }
-
-    public void testLongScriptCountAsc() throws Exception {
-        testMinDocCountOnTerms("l", Script.YES, Terms.Order.count(true));
-    }
-
     public void testLongCountDesc() throws Exception {
-        testMinDocCountOnTerms("l", Script.NO, Terms.Order.count(false));
+        testMinDocCountOnTerms("l", Script.NO, Terms.Order.count());
     }
 
     public void testLongScriptCountDesc() throws Exception {
-        testMinDocCountOnTerms("l", Script.YES, Terms.Order.count(false));
+        testMinDocCountOnTerms("l", Script.YES, Terms.Order.count());
     }
 
     public void testDoubleTermAsc() throws Exception {
@@ -253,20 +229,12 @@ public class MinDocCountTests extends AbstractTermsTestCase {
         testMinDocCountOnTerms("d", Script.YES, Terms.Order.term(false));
     }
 
-    public void testDoubleCountAsc() throws Exception {
-        testMinDocCountOnTerms("d", Script.NO, Terms.Order.count(true));
-    }
-
-    public void testDoubleScriptCountAsc() throws Exception {
-        testMinDocCountOnTerms("d", Script.YES, Terms.Order.count(true));
-    }
-
     public void testDoubleCountDesc() throws Exception {
-        testMinDocCountOnTerms("d", Script.NO, Terms.Order.count(false));
+        testMinDocCountOnTerms("d", Script.NO, Terms.Order.count());
     }
 
     public void testDoubleScriptCountDesc() throws Exception {
-        testMinDocCountOnTerms("d", Script.YES, Terms.Order.count(false));
+        testMinDocCountOnTerms("d", Script.YES, Terms.Order.count());
     }
 
     private void testMinDocCountOnTerms(String field, Script script, Terms.Order order) throws Exception {

+ 1 - 6
modules/lang-groovy/src/test/java/org/elasticsearch/messy/tests/StringTermsTests.java

@@ -1375,11 +1375,6 @@ public class StringTermsTests extends AbstractTermsTestCase {
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("avg_l", false), Terms.Order.term(true));
     }
 
-    public void testSingleValuedFieldOrderedByCountAscAndSingleValueSubAggregationAsc() throws Exception {
-        String[] expectedKeys = new String[] { "val6", "val7", "val3", "val4", "val5", "val1", "val2" };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(true), Terms.Order.aggregation("avg_l", true));
-    }
-
     public void testSingleValuedFieldOrderedBySingleValueSubAggregationAscSingleValueSubAggregationAsc() throws Exception {
         String[] expectedKeys = new String[] { "val6", "val7", "val3", "val5", "val4", "val1", "val2" };
         assertMultiSortResponse(expectedKeys, Terms.Order.aggregation("sum_d", true), Terms.Order.aggregation("avg_l", true));
@@ -1387,7 +1382,7 @@ public class StringTermsTests extends AbstractTermsTestCase {
 
     public void testSingleValuedFieldOrderedByThreeCriteria() throws Exception {
         String[] expectedKeys = new String[] { "val2", "val1", "val4", "val5", "val3", "val6", "val7" };
-        assertMultiSortResponse(expectedKeys, Terms.Order.count(false), Terms.Order.aggregation("sum_d", false),
+        assertMultiSortResponse(expectedKeys, Terms.Order.count(), Terms.Order.aggregation("sum_d", false),
                 Terms.Order.aggregation("avg_l", false));
     }
 

+ 14 - 1
rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/20_terms.yaml

@@ -350,4 +350,17 @@ setup:
   
   - match: { aggregations.date_terms.buckets.0.key_as_string: "2014-09-01T00:00:00.000Z" }
 
-  - match: { aggregations.date_terms.buckets.0.doc_count: 1 }  
+  - match: { aggregations.date_terms.buckets.0.doc_count: 1 }
+
+---
+"Terms count order test":
+  - do:
+      catch:  /Sort by ascending _count is not supported in/
+      search:
+        body: { "size" : 0, "aggs" : { "count_order" : { "terms" : { "field" : "f1", "order": {"_count": "asc"} } } } }
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "count_order" : { "terms" : { "field" : "f1", "order": "_count" } } } }
+
+