View Javadoc
1   /*
2    * #%L
3    * AggregationGroupField.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  
21  package com.allanbank.mongodb.builder;
22  
23  import com.allanbank.mongodb.bson.Element;
24  import com.allanbank.mongodb.bson.element.DocumentElement;
25  import com.allanbank.mongodb.bson.element.IntegerElement;
26  import com.allanbank.mongodb.bson.element.StringElement;
27  
28  /**
29   * AggregationGroupField holds the information for an aggregation field in an
30   * aggregate command's
31   * {@link Aggregate.Builder#group(AggregationGroupId, AggregationGroupField...)
32   * $group} pipeline operator.
33   * 
34   * @see <a href=
35   *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_group">MongoDB
36   *      Aggregate Command $group Operator</a>
37   * @api.yes This class is part of the driver's API. Public and protected members
38   *          will be deprecated for at least 1 non-bugfix release (version
39   *          numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;) before being
40   *          removed or modified.
41   * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
42   */
43  public class AggregationGroupField {
44  
45      /**
46       * Helper method for creating {@link AggregationGroupField.Builder}s using
47       * with a specific fieldName.
48       * 
49       * @param fieldName
50       *            The name of the output document field to be set.
51       * @return The builder for constructing the {@link AggregationGroupField}.
52       * @see <a href=
53       *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_group">MongoDB
54       *      Aggregate Command $group Operator</a>
55       */
56      public static AggregationGroupField.Builder set(final String fieldName) {
57          return new AggregationGroupField.Builder(fieldName);
58      }
59  
60      /** The element for the group operator's field. */
61      private final Element myElement;
62  
63      /**
64       * Creates a new AggregationGroupField.
65       * 
66       * @param name
67       *            The name of the output document field to be set.
68       * @param operator
69       *            The operator to use to perform the aggregation.
70       * @param value
71       *            The value to supply the operator.
72       */
73      protected AggregationGroupField(final String name, final String operator,
74              final int value) {
75          myElement = new DocumentElement(name, new IntegerElement(operator,
76                  value));
77      }
78  
79      /**
80       * Creates a new AggregationGroupField.
81       * 
82       * @param name
83       *            The name of the output document field to be set.
84       * @param operator
85       *            The operator to use to perform the aggregation.
86       * @param fieldRef
87       *            The field reference to use. If the <tt>fieldRef</tt> does not
88       *            start with a '$' then one will be added.
89       */
90      protected AggregationGroupField(final String name, final String operator,
91              final String fieldRef) {
92          String normailzedFieldRef = fieldRef;
93          if (!fieldRef.startsWith("$")) {
94              normailzedFieldRef = "$" + fieldRef;
95          }
96  
97          myElement = new DocumentElement(name, new StringElement(operator,
98                  normailzedFieldRef));
99      }
100 
101     /**
102      * Returns the element for the group operator's field.
103      * 
104      * @return The element for the group operator's field.
105      */
106     public Element toElement() {
107         return myElement;
108     }
109 
110     /**
111      * Builder provides the ability to construct a {@link AggregationGroupField}
112      * .
113      * <p>
114      * This {@link Builder} does not support a <tt>build()</tt> method or
115      * support chaining of method calls. Instead each builder method returns a
116      * {@link AggregationGroupField}. This is to more closely match the
117      * semantics of the group operator which cannot build complex structures for
118      * each field.
119      * </p>
120      * 
121      * @api.yes This class is part of the driver's API. Public and protected
122      *          members will be deprecated for at least 1 non-bugfix release
123      *          (version numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;)
124      *          before being removed or modified.
125      * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
126      */
127     public static class Builder {
128 
129         /**
130          * The name of the field to set with the result of the
131          * aggregation/group.
132          */
133         private final String myFieldName;
134 
135         /**
136          * Creates a new Builder.
137          * 
138          * @param fieldName
139          *            The name of the field to set with the result of the
140          *            aggregation/group.
141          */
142         public Builder(final String fieldName) {
143             myFieldName = fieldName;
144         }
145 
146         /**
147          * Constructs a new {@link AggregationGroupField} object that uses the
148          * <tt>$addToSet</tt> operator to accumulate the unique values of the
149          * <tt>fieldRef</tt>.
150          * <p>
151          * This is an alias for {@link #uniqueValuesOf(String)}.
152          * </p>
153          * 
154          * @param fieldRef
155          *            The field reference to use. If the <tt>fieldRef</tt> does
156          *            not start with a '$' then one will be added.
157          * @return The new {@link AggregationGroupField} object.
158          * @see <a href=
159          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_addToSet">MongoDB
160          *      Aggregate Command $group Operator - $addToSet</a>
161          */
162         public AggregationGroupField addToSet(final String fieldRef) {
163             return uniqueValuesOf(fieldRef);
164         }
165 
166         /**
167          * Constructs a new {@link AggregationGroupField} object that uses the
168          * <tt>$push</tt> operator to accumulate all of the values seen from the
169          * <tt>fieldRef</tt>.
170          * 
171          * @param fieldRef
172          *            The field reference to use. If the <tt>fieldRef</tt> does
173          *            not start with a '$' then one will be added.
174          * @return The new {@link AggregationGroupField} object.
175          * @see <a href=
176          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_push">MongoDB
177          *      Aggregate Command $group Operator - $push</a>
178          */
179         public AggregationGroupField all(final String fieldRef) {
180             return as("$push", fieldRef);
181         }
182 
183         /**
184          * Constructs a new {@link AggregationGroupField} object that uses the
185          * custom operator to aggregate all of the values seen from the
186          * <tt>fieldRef</tt>.
187          * 
188          * @param operator
189          *            The operator to use.
190          * @param value
191          *            The value to use in the aggregation.
192          * @return The new {@link AggregationGroupField} object.
193          * @see <a href=
194          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_group">MongoDB
195          *      Aggregate Command $group Operator</a>
196          */
197         public AggregationGroupField as(final String operator, final int value) {
198             return new AggregationGroupField(myFieldName, operator, value);
199         }
200 
201         /**
202          * Constructs a new {@link AggregationGroupField} object that uses the
203          * custom operator to aggregate all of the values seen from the
204          * <tt>fieldRef</tt>.
205          * 
206          * @param operator
207          *            The operator to use.
208          * @param fieldRef
209          *            The field reference to use. If the <tt>fieldRef</tt> does
210          *            not start with a '$' then one will be added.
211          * @return The new {@link AggregationGroupField} object.
212          * @see <a href=
213          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_group">MongoDB
214          *      Aggregate Command $group Operator</a>
215          */
216         public AggregationGroupField as(final String operator,
217                 final String fieldRef) {
218             return new AggregationGroupField(myFieldName, operator, fieldRef);
219         }
220 
221         /**
222          * Constructs a new {@link AggregationGroupField} object that uses the
223          * <tt>$avg</tt> operator to compute the average value seen from the
224          * <tt>fieldRef</tt>.
225          * 
226          * @param fieldRef
227          *            The field reference to use. If the <tt>fieldRef</tt> does
228          *            not start with a '$' then one will be added.
229          * @return The new {@link AggregationGroupField} object.
230          * @see <a href=
231          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_avg">MongoDB
232          *      Aggregate Command $group Operator - $avg</a>
233          */
234         public AggregationGroupField average(final String fieldRef) {
235             return as("$avg", fieldRef);
236         }
237 
238         /**
239          * Constructs a new {@link AggregationGroupField} object that uses the
240          * <tt>$sum</tt> operator to count all of the input documents.
241          * 
242          * @return The new {@link AggregationGroupField} object.
243          * @see <a href=
244          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_sum">MongoDB
245          *      Aggregate Command $group Operator - $sum</a>
246          */
247         public AggregationGroupField count() {
248             return as("$sum", 1);
249         }
250 
251         /**
252          * Constructs a new {@link AggregationGroupField} object that uses the
253          * <tt>$first</tt> operator to use the first value seen from the
254          * <tt>fieldRef</tt>.
255          * 
256          * @param fieldRef
257          *            The field reference to use. If the <tt>fieldRef</tt> does
258          *            not start with a '$' then one will be added.
259          * @return The new {@link AggregationGroupField} object.
260          * @see <a href=
261          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_first">MongoDB
262          *      Aggregate Command $group Operator - $first</a>
263          */
264         public AggregationGroupField first(final String fieldRef) {
265             return as("$first", fieldRef);
266         }
267 
268         /**
269          * Constructs a new {@link AggregationGroupField} object that uses the
270          * <tt>$last</tt> operator to use the last value seen from the
271          * <tt>fieldRef</tt>.
272          * 
273          * @param fieldRef
274          *            The field reference to use. If the <tt>fieldRef</tt> does
275          *            not start with a '$' then one will be added.
276          * @return The new {@link AggregationGroupField} object.
277          * @see <a href=
278          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_last">MongoDB
279          *      Aggregate Command $group Operator - $last</a>
280          */
281         public AggregationGroupField last(final String fieldRef) {
282             return as("$last", fieldRef);
283         }
284 
285         /**
286          * Constructs a new {@link AggregationGroupField} object that uses the
287          * <tt>$max</tt> operator to use the maximum value seen from the
288          * <tt>fieldRef</tt>.
289          * 
290          * @param fieldRef
291          *            The field reference to use. If the <tt>fieldRef</tt> does
292          *            not start with a '$' then one will be added.
293          * @return The new {@link AggregationGroupField} object.
294          * @see <a href=
295          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_max">MongoDB
296          *      Aggregate Command $group Operator - $max</a>
297          */
298         public AggregationGroupField maximum(final String fieldRef) {
299             return as("$max", fieldRef);
300         }
301 
302         /**
303          * Constructs a new {@link AggregationGroupField} object that uses the
304          * <tt>$min</tt> operator to use the minimum value seen from the
305          * <tt>fieldRef</tt>.
306          * 
307          * @param fieldRef
308          *            The field reference to use. If the <tt>fieldRef</tt> does
309          *            not start with a '$' then one will be added.
310          * @return The new {@link AggregationGroupField} object.
311          * @see <a href=
312          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_min">MongoDB
313          *      Aggregate Command $group Operator - $min</a>
314          */
315         public AggregationGroupField minimum(final String fieldRef) {
316             return as("$min", fieldRef);
317         }
318 
319         /**
320          * Constructs a new {@link AggregationGroupField} object that uses the
321          * <tt>$push</tt> operator to accumulate all of the values seen from the
322          * <tt>fieldRef</tt>.
323          * <p>
324          * This is an alias for {@link #all(String)}.
325          * </p>
326          * 
327          * @param fieldRef
328          *            The field reference to use. If the <tt>fieldRef</tt> does
329          *            not start with a '$' then one will be added.
330          * @return The new {@link AggregationGroupField} object.
331          * @see <a href=
332          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_push">MongoDB
333          *      Aggregate Command $group Operator - $push</a>
334          */
335         public AggregationGroupField push(final String fieldRef) {
336             return all(fieldRef);
337         }
338 
339         /**
340          * Constructs a new {@link AggregationGroupField} object that uses the
341          * <tt>$sum</tt> operator to sum all of the values seen from the
342          * <tt>fieldRef</tt>.
343          * 
344          * @param fieldRef
345          *            The field reference to use. If the <tt>fieldRef</tt> does
346          *            not start with a '$' then one will be added.
347          * @return The new {@link AggregationGroupField} object.
348          * @see <a href=
349          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_sum">MongoDB
350          *      Aggregate Command $group Operator - $sum</a>
351          */
352         public AggregationGroupField sum(final String fieldRef) {
353             return as("$sum", fieldRef);
354         }
355 
356         /**
357          * Constructs a new {@link AggregationGroupField} object that uses the
358          * <tt>$addToSet</tt> operator to accumulate the unique values of the
359          * <tt>fieldRef</tt>.
360          * 
361          * @param fieldRef
362          *            The field reference to use. If the <tt>fieldRef</tt> does
363          *            not start with a '$' then one will be added.
364          * @return The new {@link AggregationGroupField} object.
365          * @see <a href=
366          *      "http://docs.mongodb.org/manual/reference/aggregation/#_S_addToSet">MongoDB
367          *      Aggregate Command $group Operator - $addToSet</a>
368          */
369         public AggregationGroupField uniqueValuesOf(final String fieldRef) {
370             return as("$addToSet", fieldRef);
371         }
372     }
373 }