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