    001    /*
    002     * Copyright (c) 2007-2014 Concurrent, Inc. All Rights Reserved.
    003     *
    004     * Project and contact information: http://www.cascading.org/
    005     *
    006     * This file is part of the Cascading project.
    007     *
    008     * Licensed under the Apache License, Version 2.0 (the "License");
    009     * you may not use this file except in compliance with the License.
    010     * You may obtain a copy of the License at
    011     *
    012     *     http://www.apache.org/licenses/LICENSE-2.0
    013     *
    014     * Unless required by applicable law or agreed to in writing, software
    015     * distributed under the License is distributed on an "AS IS" BASIS,
    016     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    017     * See the License for the specific language governing permissions and
    018     * limitations under the License.
    019     */
    020
    021    package cascading.pipe.assembly;
    022
    023    import java.beans.ConstructorProperties;
    024
    025    import cascading.flow.FlowProcess;
    026    import cascading.operation.aggregator.Sum;
    027    import cascading.pipe.Pipe;
    028    import cascading.tuple.Fields;
    029    import cascading.tuple.Tuple;
    030    import cascading.tuple.TupleEntry;
    031    import cascading.tuple.Tuples;
    032
    033    /**
    034     * Class CountBy is used to count duplicates in a tuple stream.
    035     * <p/>
    036     * Typically finding the count of a field in a tuple stream relies on a {@link cascading.pipe.GroupBy} and a {@link cascading.operation.aggregator.Count}
    037     * {@link cascading.operation.Aggregator} operation.
    038     * <p/>
    039     * If {@code include} is {@link Include#NO_NULLS}, argument tuples with all null values will be ignored. When counting
    040     * the occurrence of a single field (when {@code valueFields} is set on the constructor), this is the same behavior
    041     * as {@code select count(foo) ...} in SQL. If {@code include} is
    042     * {@link Include#ONLY_NULLS} then only tuples will all null values will be counted.
    043     * <p/>
    044     * This SubAssembly also uses the {@link CountBy.CountPartials} {@link AggregateBy.Functor}
    045     * to count field values before the GroupBy operator to reduce IO over the network.
    046     * <p/>
    047     * This strategy is similar to using {@code combiners}, except no sorting or serialization is invoked and results
    048     * in a much simpler mechanism.
    049     * <p/>
    050     * The {@code threshold} value tells the underlying CountPartials functions how many unique key counts to accumulate
    051     * in the LRU cache, before emitting the least recently used entry.
    052     * <p/>
    053     * By default, either the value of {@link #AGGREGATE_BY_THRESHOLD} System property or {@link AggregateBy#DEFAULT_THRESHOLD}
    054     * will be used.
    055     *
    056     * @see AggregateBy
    057     */
    058    public class CountBy extends AggregateBy
    059      {
    060      /** DEFAULT_THRESHOLD */
    061      @Deprecated
    062      public static final int DEFAULT_THRESHOLD = 10000;
    063
    064      public enum Include
    065        {
    066          ALL,
    067          NO_NULLS,
    068          ONLY_NULLS
    069        }
    070
    071      /**
    072       * Class CountPartials is a {@link AggregateBy.Functor} that is used to count observed duplicates from the tuple stream.
    073       * <p/>
    074       * Use this class typically in tandem with a {@link cascading.operation.aggregator.Sum}
    075       * {@link cascading.operation.Aggregator} in order to improve counting performance by removing as many values
    076       * as possible before the intermediate {@link cascading.pipe.GroupBy} operator.
    077       *
    078       * @see CountBy
    079       */
    080      public static class CountPartials implements Functor
    081        {
    082        private final Fields declaredFields;
    083        private final Include include;
    084
    085        /**
    086         * Constructor CountPartials creates a new CountPartials instance.
    087         *
    088         * @param declaredFields of type Fields
    089         */
    090        public CountPartials( Fields declaredFields )
    091          {
    092          this( declaredFields, Include.ALL );
    093          }
    094
    095        public CountPartials( Fields declaredFields, Include include )
    096          {
    097          this.declaredFields = declaredFields;
    098          this.include = include;
    099
    100          if( !declaredFields.isDeclarator() || declaredFields.size() != 1 )
    101            throw new IllegalArgumentException( "declaredFields should declare only one field name" );
    102          }
    103
    104        @Override
    105        public Fields getDeclaredFields()
    106          {
    107          return declaredFields;
    108          }
    109
    110        @Override
    111        public Tuple aggregate( FlowProcess flowProcess, TupleEntry args, Tuple context )
    112          {
    113          if( context == null )
    114            context = new Tuple( 0L );
    115
    116          switch( include )
    117            {
    118            case ALL:
    119              break;
    120
    121            case NO_NULLS:
    122              if( Tuples.frequency( args, null ) == args.size() )
    123                return context;
    124
    125              break;
    126
    127            case ONLY_NULLS:
    128              if( Tuples.frequency( args, null ) != args.size() )
    129                return context;
    130
    131              break;
    132            }
    133
    134          context.set( 0, context.getLong( 0 ) + 1L );
    135
    136          return context;
    137          }
    138
    139        @Override
    140        public Tuple complete( FlowProcess flowProcess, Tuple context )
    141          {
    142          return context;
    143          }
    144        }
    145
    146      //// AggregateBy param constructors
    147
    148      /**
    149       * Constructor CountBy creates a new CountBy instance. Use this constructor when used with a {@link AggregateBy}
    150       * instance.
    151       *
    152       * @param countField of type Fields
    153       */
    154      @ConstructorProperties({"countField"})
    155      public CountBy( Fields countField )
    156        {
    157        super( Fields.ALL, new CountPartials( countField.applyTypes( Long.TYPE ) ), new Sum( countField.applyTypes( Long.TYPE ) ) );
    158        }
    159
    160      /**
    161       * Constructor CountBy creates a new CountBy instance. Use this constructor when used with a {@link AggregateBy}
    162       * instance.
    163       *
    164       * @param countField of type Fields
    165       * @param include    of type Include
    166       */
    167      @ConstructorProperties({"countField", "include"})
    168      public CountBy( Fields countField, Include include )
    169        {
    170        super( Fields.ALL, new CountPartials( countField.applyTypes( Long.TYPE ), include ), new Sum( countField.applyTypes( Long.TYPE ) ) );
    171        }
    172
    173      /**
    174       * Constructor CountBy creates a new CountBy instance. Use this constructor when used with a {@link AggregateBy}
    175       * instance.
    176       *
    177       * @param countField of type Fields
    178       */
    179      @ConstructorProperties({"valueFields", "countField"})
    180      public CountBy( Fields valueFields, Fields countField )
    181        {
    182        super( valueFields, new CountPartials( countField.applyTypes( Long.TYPE ) ), new Sum( countField.applyTypes( Long.TYPE ) ) );
    183        }
    184
    185      /**
    186       * Constructor CountBy creates a new CountBy instance. Use this constructor when used with a {@link AggregateBy}
    187       * instance.
    188       *
    189       * @param countField of type Fields
    190       */
    191      @ConstructorProperties({"valueFields", "countField", "include"})
    192      public CountBy( Fields valueFields, Fields countField, Include include )
    193        {
    194        super( valueFields, new CountPartials( countField.applyTypes( Long.TYPE ), include ), new Sum( countField.applyTypes( Long.TYPE ) ) );
    195        }
    196
    197      ///////
    198
    199      /**
    200       * Constructor CountBy creates a new CountBy instance.
    201       *
    202       * @param pipe           of type Pipe
    203       * @param groupingFields of type Fields
    204       * @param countField     of type Fields
    205       */
    206      @ConstructorProperties({"pipe", "groupingFields", "countField"})
    207      public CountBy( Pipe pipe, Fields groupingFields, Fields countField )
    208        {
    209        this( null, pipe, groupingFields, countField );
    210        }
    211
    212      /**
    213       * Constructor CountBy creates a new CountBy instance.
    214       *
    215       * @param pipe           of type Pipe
    216       * @param groupingFields of type Fields
    217       * @param countField     fo type Fields
    218       * @param threshold      of type int
    219       */
    220      @ConstructorProperties({"pipe", "groupingFields", "countField", "threshold"})
    221      public CountBy( Pipe pipe, Fields groupingFields, Fields countField, int threshold )
    222        {
    223        this( null, pipe, groupingFields, countField, threshold );
    224        }
    225
    226      /**
    227       * Constructor CountBy creates a new CountBy instance.
    228       *
    229       * @param name           of type String
    230       * @param pipe           of type Pipe
    231       * @param groupingFields of type Fields
    232       * @param countField     of type Fields
    233       */
    234      @ConstructorProperties({"name", "pipe", "groupingFields", "countField"})
    235      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields countField )
    236        {
    237        this( name, pipe, groupingFields, countField, USE_DEFAULT_THRESHOLD );
    238        }
    239
    240      /**
    241       * Constructor CountBy creates a new CountBy instance.
    242       *
    243       * @param name           of type String
    244       * @param pipe           of type Pipe
    245       * @param groupingFields of type Fields
    246       * @param countField     of type Fields
    247       * @param threshold      of type int
    248       */
    249      @ConstructorProperties({"name", "pipe", "groupingFields", "countField", "threshold"})
    250      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields countField, int threshold )
    251        {
    252        this( name, Pipe.pipes( pipe ), groupingFields, countField, threshold );
    253        }
    254
    255      /**
    256       * Constructor CountBy creates a new CountBy instance.
    257       *
    258       * @param pipes          of type Pipe[]
    259       * @param groupingFields of type Fields
    260       * @param countField     of type Fields
    261       */
    262      @ConstructorProperties({"pipes", "groupingFields", "countField"})
    263      public CountBy( Pipe[] pipes, Fields groupingFields, Fields countField )
    264        {
    265        this( null, pipes, groupingFields, countField, USE_DEFAULT_THRESHOLD );
    266        }
    267
    268      /**
    269       * Constructor CountBy creates a new CountBy instance.
    270       *
    271       * @param pipes          of type Pipe[]
    272       * @param groupingFields of type Fields
    273       * @param countField     of type Fields
    274       * @param threshold      of type int
    275       */
    276      @ConstructorProperties({"pipes", "groupingFields", "countField", "threshold"})
    277      public CountBy( Pipe[] pipes, Fields groupingFields, Fields countField, int threshold )
    278        {
    279        this( null, pipes, groupingFields, countField, threshold );
    280        }
    281
    282      /**
    283       * Constructor CountBy creates a new CountBy instance.
    284       *
    285       * @param name           of type String
    286       * @param pipes          of type Pipe[]
    287       * @param groupingFields of type Fields
    288       * @param countField     of type Fields
    289       */
    290      @ConstructorProperties({"name", "pipes", "groupingFields", "countField"})
    291      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields countField )
    292        {
    293        this( name, pipes, groupingFields, countField, USE_DEFAULT_THRESHOLD );
    294        }
    295
    296      /**
    297       * Constructor CountBy creates a new CountBy instance.
    298       *
    299       * @param name           of type String
    300       * @param pipes          of type Pipe[]
    301       * @param groupingFields of type Fields
    302       * @param countField     of type Fields
    303       * @param threshold      of type int
    304       */
    305      @ConstructorProperties({"name", "pipes", "groupingFields", "countField", "threshold"})
    306      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields countField, int threshold )
    307        {
    308        super( name, pipes, groupingFields, groupingFields, new CountPartials( countField.applyTypes( Long.TYPE ) ), new Sum( countField.applyTypes( Long.TYPE ) ), threshold );
    309        }
    310
    311      ///////
    312
    313      /**
    314       * Constructor CountBy creates a new CountBy instance.
    315       *
    316       * @param pipe           of type Pipe
    317       * @param groupingFields of type Fields
    318       * @param countField     of type Fields
    319       * @param include        of type Include
    320       */
    321      @ConstructorProperties({"pipe", "groupingFields", "countField", "include"})
    322      public CountBy( Pipe pipe, Fields groupingFields, Fields countField, Include include )
    323        {
    324        this( null, pipe, groupingFields, countField, include );
    325        }
    326
    327      /**
    328       * Constructor CountBy creates a new CountBy instance.
    329       *
    330       * @param pipe           of type Pipe
    331       * @param groupingFields of type Fields
    332       * @param countField     fo type Fields
    333       * @param include        of type Include
    334       * @param threshold      of type int
    335       */
    336      @ConstructorProperties({"pipe", "groupingFields", "countField", "include", "threshold"})
    337      public CountBy( Pipe pipe, Fields groupingFields, Fields countField, Include include, int threshold )
    338        {
    339        this( null, pipe, groupingFields, countField, include, threshold );
    340        }
    341
    342      /**
    343       * Constructor CountBy creates a new CountBy instance.
    344       *
    345       * @param name           of type String
    346       * @param pipe           of type Pipe
    347       * @param groupingFields of type Fields
    348       * @param countField     of type Fields
    349       * @param include        of type Include
    350       */
    351      @ConstructorProperties({"name", "pipe", "groupingFields", "countField", "include"})
    352      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields countField, Include include )
    353        {
    354        this( name, pipe, groupingFields, countField, include, USE_DEFAULT_THRESHOLD );
    355        }
    356
    357      /**
    358       * Constructor CountBy creates a new CountBy instance.
    359       *
    360       * @param name           of type String
    361       * @param pipe           of type Pipe
    362       * @param groupingFields of type Fields
    363       * @param countField     of type Fields
    364       * @param include        of type Include
    365       * @param threshold      of type int
    366       */
    367      @ConstructorProperties({"name", "pipe", "groupingFields", "countField", "include", "threshold"})
    368      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields countField, Include include, int threshold )
    369        {
    370        this( name, Pipe.pipes( pipe ), groupingFields, countField, include, threshold );
    371        }
    372
    373      /**
    374       * Constructor CountBy creates a new CountBy instance.
    375       *
    376       * @param pipes          of type Pipe[]
    377       * @param groupingFields of type Fields
    378       * @param countField     of type Fields
    379       * @param include        of type Include
    380       */
    381      @ConstructorProperties({"pipes", "groupingFields", "countField", "include"})
    382      public CountBy( Pipe[] pipes, Fields groupingFields, Fields countField, Include include )
    383        {
    384        this( null, pipes, groupingFields, countField, include, USE_DEFAULT_THRESHOLD );
    385        }
    386
    387      /**
    388       * Constructor CountBy creates a new CountBy instance.
    389       *
    390       * @param pipes          of type Pipe[]
    391       * @param groupingFields of type Fields
    392       * @param countField     of type Fields
    393       * @param include        of type Include
    394       * @param threshold      of type int
    395       */
    396      @ConstructorProperties({"pipes", "groupingFields", "countField", "include", "threshold"})
    397      public CountBy( Pipe[] pipes, Fields groupingFields, Fields countField, Include include, int threshold )
    398        {
    399        this( null, pipes, groupingFields, countField, include, threshold );
    400        }
    401
    402      /**
    403       * Constructor CountBy creates a new CountBy instance.
    404       *
    405       * @param name           of type String
    406       * @param pipes          of type Pipe[]
    407       * @param groupingFields of type Fields
    408       * @param countField     of type Fields
    409       * @param include        of type Include
    410       */
    411      @ConstructorProperties({"name", "pipes", "groupingFields", "countField", "include"})
    412      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields countField, Include include )
    413        {
    414        this( name, pipes, groupingFields, countField, include, USE_DEFAULT_THRESHOLD );
    415        }
    416
    417      /**
    418       * Constructor CountBy creates a new CountBy instance.
    419       *
    420       * @param name           of type String
    421       * @param pipes          of type Pipe[]
    422       * @param groupingFields of type Fields
    423       * @param countField     of type Fields
    424       * @param include        of type Include
    425       * @param threshold      of type int
    426       */
    427      @ConstructorProperties({"name", "pipes", "groupingFields", "countField", "include", "threshold"})
    428      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields countField, Include include, int threshold )
    429        {
    430        super( name, pipes, groupingFields, groupingFields, new CountPartials( countField.applyTypes( Long.TYPE ), include ), new Sum( countField.applyTypes( Long.TYPE ) ), threshold );
    431        }
    432
    433    ////////////
    434
    435      /**
    436       * Constructor CountBy creates a new CountBy instance.
    437       *
    438       * @param pipe           of type Pipe
    439       * @param groupingFields of type Fields
    440       * @param valueFields    of type Fields
    441       * @param countField     of type Fields
    442       */
    443      @ConstructorProperties({"pipe", "groupingFields", "valueFields", "countField"})
    444      public CountBy( Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField )
    445        {
    446        this( null, pipe, groupingFields, valueFields, countField, Include.ALL );
    447        }
    448
    449      /**
    450       * Constructor CountBy creates a new CountBy instance.
    451       *
    452       * @param pipe           of type Pipe
    453       * @param groupingFields of type Fields
    454       * @param valueFields    of type Fields
    455       * @param countField     fo type Fields
    456       * @param threshold      of type int
    457       */
    458      @ConstructorProperties({"pipe", "groupingFields", "valueFields", "countField", "threshold"})
    459      public CountBy( Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, int threshold )
    460        {
    461        this( null, pipe, groupingFields, valueFields, countField, threshold );
    462        }
    463
    464      /**
    465       * Constructor CountBy creates a new CountBy instance.
    466       *
    467       * @param name           of type String
    468       * @param pipe           of type Pipe
    469       * @param groupingFields of type Fields
    470       * @param valueFields    of type Fields
    471       * @param countField     of type Fields
    472       */
    473      @ConstructorProperties({"name", "pipe", "groupingFields", "valueFields", "countField"})
    474      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField )
    475        {
    476        this( name, pipe, groupingFields, valueFields, countField, USE_DEFAULT_THRESHOLD );
    477        }
    478
    479      /**
    480       * Constructor CountBy creates a new CountBy instance.
    481       *
    482       * @param name           of type String
    483       * @param pipe           of type Pipe
    484       * @param groupingFields of type Fields
    485       * @param valueFields    of type Fields
    486       * @param countField     of type Fields
    487       * @param threshold      of type int
    488       */
    489      @ConstructorProperties({"name", "pipe", "groupingFields", "valueFields", "countField", "threshold"})
    490      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, int threshold )
    491        {
    492        this( name, Pipe.pipes( pipe ), groupingFields, valueFields, countField, threshold );
    493        }
    494
    495      /**
    496       * Constructor CountBy creates a new CountBy instance.
    497       *
    498       * @param pipes          of type Pipe[]
    499       * @param groupingFields of type Fields
    500       * @param valueFields    of type Fields
    501       * @param countField     of type Fields
    502       */
    503      @ConstructorProperties({"pipes", "groupingFields", "valueFields", "countField"})
    504      public CountBy( Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField )
    505        {
    506        this( null, pipes, groupingFields, valueFields, countField, USE_DEFAULT_THRESHOLD );
    507        }
    508
    509      /**
    510       * Constructor CountBy creates a new CountBy instance.
    511       *
    512       * @param pipes          of type Pipe[]
    513       * @param groupingFields of type Fields
    514       * @param valueFields    of type Fields
    515       * @param countField     of type Fields
    516       * @param threshold      of type int
    517       */
    518      @ConstructorProperties({"pipes", "groupingFields", "valueFields", "countField", "threshold"})
    519      public CountBy( Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, int threshold )
    520        {
    521        this( null, pipes, groupingFields, valueFields, countField, threshold );
    522        }
    523
    524      /**
    525       * Constructor CountBy creates a new CountBy instance.
    526       *
    527       * @param name           of type String
    528       * @param pipes          of type Pipe[]
    529       * @param groupingFields of type Fields
    530       * @param valueFields    of type Fields
    531       * @param countField     of type Fields
    532       */
    533      @ConstructorProperties({"name", "pipes", "groupingFields", "valueFields", "countField"})
    534      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField )
    535        {
    536        this( name, pipes, groupingFields, valueFields, countField, USE_DEFAULT_THRESHOLD );
    537        }
    538
    539      /**
    540       * Constructor CountBy creates a new CountBy instance.
    541       *
    542       * @param name           of type String
    543       * @param pipes          of type Pipe[]
    544       * @param groupingFields of type Fields
    545       * @param valueFields    of type Fields
    546       * @param countField     of type Fields
    547       * @param threshold      of type int
    548       */
    549      @ConstructorProperties({"name", "pipes", "groupingFields", "valueFields", "countField", "threshold"})
    550      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, int threshold )
    551        {
    552        super( name, pipes, groupingFields, valueFields, new CountPartials( countField.applyTypes( Long.TYPE ) ), new Sum( countField.applyTypes( Long.TYPE ) ), threshold );
    553        }
    554
    555    ////////////
    556
    557      /**
    558       * Constructor CountBy creates a new CountBy instance.
    559       *
    560       * @param pipe           of type Pipe
    561       * @param groupingFields of type Fields
    562       * @param valueFields    of type Fields
    563       * @param countField     of type Fields
    564       * @param include        of type Include
    565       */
    566      @ConstructorProperties({"pipe", "groupingFields", "valueFields", "countField", "include"})
    567      public CountBy( Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, Include include )
    568        {
    569        this( null, pipe, groupingFields, valueFields, countField, include );
    570        }
    571
    572      /**
    573       * Constructor CountBy creates a new CountBy instance.
    574       *
    575       * @param pipe           of type Pipe
    576       * @param groupingFields of type Fields
    577       * @param valueFields    of type Fields
    578       * @param countField     fo type Fields
    579       * @param include        of type Include
    580       * @param threshold      of type int
    581       */
    582      @ConstructorProperties({"pipe", "groupingFields", "valueFields", "countField", "include", "threshold"})
    583      public CountBy( Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, Include include, int threshold )
    584        {
    585        this( null, pipe, groupingFields, valueFields, countField, include, threshold );
    586        }
    587
    588      /**
    589       * Constructor CountBy creates a new CountBy instance.
    590       *
    591       * @param name           of type String
    592       * @param pipe           of type Pipe
    593       * @param valueFields    of type Fields
    594       * @param groupingFields of type Fields
    595       * @param countField     of type Fields
    596       * @param include        of type Include
    597       */
    598      @ConstructorProperties({"name", "pipe", "groupingFields", "valueFields", "countField", "include"})
    599      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, Include include )
    600        {
    601        this( name, pipe, groupingFields, valueFields, countField, include, USE_DEFAULT_THRESHOLD );
    602        }
    603
    604      /**
    605       * Constructor CountBy creates a new CountBy instance.
    606       *
    607       * @param name           of type String
    608       * @param pipe           of type Pipe
    609       * @param groupingFields of type Fields
    610       * @param valueFields    of type Fields
    611       * @param countField     of type Fields
    612       * @param include        of type Include
    613       * @param threshold      of type int
    614       */
    615      @ConstructorProperties({"name", "pipe", "groupingFields", "valueFields", "countField", "include", "threshold"})
    616      public CountBy( String name, Pipe pipe, Fields groupingFields, Fields valueFields, Fields countField, Include include, int threshold )
    617        {
    618        this( name, Pipe.pipes( pipe ), groupingFields, valueFields, countField, include, threshold );
    619        }
    620
    621      /**
    622       * Constructor CountBy creates a new CountBy instance.
    623       *
    624       * @param pipes          of type Pipe[]
    625       * @param groupingFields of type Fields
    626       * @param valueFields    of type Fields
    627       * @param countField     of type Fields
    628       * @param include        of type Include
    629       */
    630      @ConstructorProperties({"pipes", "groupingFields", "valueFields", "countField", "include"})
    631      public CountBy( Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, Include include )
    632        {
    633        this( null, pipes, groupingFields, valueFields, countField, include, USE_DEFAULT_THRESHOLD );
    634        }
    635
    636      /**
    637       * Constructor CountBy creates a new CountBy instance.
    638       *
    639       * @param pipes          of type Pipe[]
    640       * @param groupingFields of type Fields
    641       * @param valueFields    of type Fields
    642       * @param countField     of type Fields
    643       * @param include        of type Include
    644       * @param threshold      of type int
    645       */
    646      @ConstructorProperties({"pipes", "groupingFields", "valueFields", "countField", "include", "threshold"})
    647      public CountBy( Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, Include include, int threshold )
    648        {
    649        this( null, pipes, groupingFields, valueFields, countField, include, threshold );
    650        }
    651
    652      /**
    653       * Constructor CountBy creates a new CountBy instance.
    654       *
    655       * @param name           of type String
    656       * @param pipes          of type Pipe[]
    657       * @param groupingFields of type Fields
    658       * @param valueFields    of type Fields
    659       * @param countField     of type Fields
    660       * @param include        of type Include
    661       */
    662      @ConstructorProperties({"name", "pipes", "groupingFields", "valueFields", "countField", "include"})
    663      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, Include include )
    664        {
    665        this( name, pipes, groupingFields, valueFields, countField, include, USE_DEFAULT_THRESHOLD );
    666        }
    667
    668      /**
    669       * Constructor CountBy creates a new CountBy instance.
    670       *
    671       * @param name           of type String
    672       * @param pipes          of type Pipe[]
    673       * @param groupingFields of type Fields
    674       * @param valueFields    of type Fields
    675       * @param countField     of type Fields
    676       * @param include        of type Include
    677       * @param threshold      of type int
    678       */
    679      @ConstructorProperties({"name", "pipes", "groupingFields", "valueFields", "countField", "include", "threshold"})
    680      public CountBy( String name, Pipe[] pipes, Fields groupingFields, Fields valueFields, Fields countField, Include include, int threshold )
    681        {
    682        super( name, pipes, groupingFields, valueFields, new CountPartials( countField.applyTypes( Long.TYPE ), include ), new Sum( countField.applyTypes( Long.TYPE ) ), threshold );
    683        }
    684      }