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      }