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 <major>.<minor>.<bugfix>) 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 <major>.<minor>.<bugfix>)
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 }