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