1 /*
2 * #%L
3 * Expressions.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.expression;
22
23 import static com.allanbank.mongodb.bson.builder.BuilderFactory.d;
24
25 import java.util.Arrays;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.regex.Pattern;
29
30 import com.allanbank.mongodb.bson.DocumentAssignable;
31 import com.allanbank.mongodb.bson.Element;
32 import com.allanbank.mongodb.bson.builder.BuilderFactory;
33 import com.allanbank.mongodb.bson.element.BooleanElement;
34 import com.allanbank.mongodb.bson.element.DocumentElement;
35 import com.allanbank.mongodb.bson.element.DoubleElement;
36 import com.allanbank.mongodb.bson.element.IntegerElement;
37 import com.allanbank.mongodb.bson.element.LongElement;
38 import com.allanbank.mongodb.bson.element.MongoTimestampElement;
39 import com.allanbank.mongodb.bson.element.NullElement;
40 import com.allanbank.mongodb.bson.element.ObjectId;
41 import com.allanbank.mongodb.bson.element.ObjectIdElement;
42 import com.allanbank.mongodb.bson.element.RegularExpressionElement;
43 import com.allanbank.mongodb.bson.element.StringElement;
44 import com.allanbank.mongodb.bson.element.TimestampElement;
45
46 /**
47 * Expressions provides a collection of static helper method for constructing
48 * complex expression.
49 *
50 * @api.yes This class is part of the driver's API. Public and protected members
51 * will be deprecated for at least 1 non-bugfix release (version
52 * numbers are <major>.<minor>.<bugfix>) before being
53 * removed or modified.
54 * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
55 */
56 public final class Expressions {
57
58 /** The {@value} operator token */
59 public static final String ADD = "$add";
60
61 /** The {@value} operator token */
62 public static final String ALL_ELEMENTS_TRUE = "$allElementsTrue";
63
64 /** The {@value} operator token */
65 public static final String AND = "$and";
66
67 /** The {@value} operator token */
68 public static final String ANY_ELEMENT_TRUE = "$anyElementTrue";
69
70 /** The {@value} operator token */
71 public static final String COMPARE = "$cmp";
72
73 /** The {@value} operator token */
74 public static final String CONCATENATE = "$concat";
75
76 /** The {@value} operator token */
77 public static final String CONDITION = "$cond";
78
79 /** The {@value} operator token */
80 public static final String DAY_OF_MONTH = "$dayOfMonth";
81
82 /** The {@value} operator token */
83 public static final String DAY_OF_WEEK = "$dayOfWeek";
84
85 /** The {@value} operator token */
86 public static final String DAY_OF_YEAR = "$dayOfYear";
87
88 /** The {@value} operator token */
89 public static final String DIVIDE = "$divide";
90
91 /** The {@value} operator token */
92 public static final String EQUAL = "$eq";
93
94 /** The {@value} operator token */
95 public static final String GREATER_THAN = "$gt";
96
97 /** The {@value} operator token */
98 public static final String GREATER_THAN_OR_EQUAL = "$gte";
99
100 /** The {@value} operator token */
101 public static final String HOUR = "$hour";
102
103 /** The {@value} operator token */
104 public static final String IF_NULL = "$ifNull";
105
106 /** The {@value} operator token */
107 public static final String LESS_THAN = "$lt";
108
109 /** The {@value} operator token */
110 public static final String LESS_THAN_OR_EQUAL = "$lte";
111
112 /** The {@value} operator token */
113 public static final String LITERAL = "$literal";
114
115 /** The {@value} operator token */
116 public static final String MILLISECOND = "$millisecond";
117
118 /** The {@value} operator token */
119 public static final String MINUTE = "$minute";
120
121 /** The {@value} operator token */
122 public static final String MODULO = "$mod";
123
124 /** The {@value} operator token */
125 public static final String MONTH = "$month";
126
127 /** The {@value} operator token */
128 public static final String MULTIPLY = "$multiply";
129
130 /** The {@value} operator token */
131 public static final String NOT = "$not";
132
133 /** The {@value} operator token */
134 public static final String NOT_EQUAL = "$ne";
135
136 /** The {@value} operator token */
137 public static final String OR = "$or";
138
139 /** The {@value} operator token */
140 public static final String SECOND = "$second";
141
142 /** The {@value} operator token */
143 public static final String SET_DIFFERENCE = "$setDifference";
144
145 /** The {@value} operator token */
146 public static final String SET_EQUALS = "$setEquals";
147
148 /** The {@value} operator token */
149 public static final String SET_INTERSECTION = "$setIntersection";
150
151 /** The {@value} operator token */
152 public static final String SET_IS_SUBSET = "$setIsSubset";
153
154 /** The {@value} operator token */
155 public static final String SET_UNION = "$setUnion";
156
157 /** The {@value} operator token */
158 public static final String SIZE = "$size";
159
160 /** The {@value} operator token */
161 public static final String STRING_CASE_INSENSITIVE_COMPARE = "$strcasecmp";
162
163 /** The {@value} operator token */
164 public static final String SUB_STRING = "$substr";
165
166 /** The {@value} operator token */
167 public static final String SUBTRACT = "$subtract";
168
169 /** The {@value} operator token */
170 public static final String TO_LOWER = "$toLower";
171
172 /** The {@value} operator token */
173 public static final String TO_UPPER = "$toUpper";
174
175 /** The {@value} operator token */
176 public static final String WEEK = "$week";
177
178 /** The {@value} operator token */
179 public static final String YEAR = "$year";
180
181 /**
182 * Returns an {@link NaryExpression} {@value #ADD} expression.
183 *
184 * @param expressions
185 * The sub-expressions.
186 * @return The {@link NaryExpression} {@value #ADD} expression.
187 */
188 public static NaryExpression add(final Expression... expressions) {
189 return new NaryExpression(ADD, expressions);
190 }
191
192 /**
193 * Returns a {@link UnaryExpression} {@value #ALL_ELEMENTS_TRUE} expression.
194 *
195 * @param expression
196 * The expression that will be evaluated to create the set to
197 * inspect for a true element.
198 * @return The {@link UnaryExpression} {@value #ALL_ELEMENTS_TRUE}
199 * expression.
200 */
201 public static UnaryExpression allElementsTrue(final Expression expression) {
202 return new UnaryExpression(ALL_ELEMENTS_TRUE, expression);
203 }
204
205 /**
206 * Returns an {@link NaryExpression} {@value #AND} expression.
207 *
208 * @param expressions
209 * The sub-expressions.
210 * @return The {@link NaryExpression} {@value #AND} expression.
211 */
212 public static NaryExpression and(final Expression... expressions) {
213 return new NaryExpression(AND, expressions);
214 }
215
216 /**
217 * Returns a {@link UnaryExpression} {@value #ANY_ELEMENT_TRUE} expression.
218 *
219 * @param expression
220 * The expression that will be evaluated to create the set to
221 * inspect for a true element.
222 * @return The {@link UnaryExpression} {@value #ANY_ELEMENT_TRUE}
223 * expression.
224 */
225 public static UnaryExpression anyElementTrue(final Expression expression) {
226 return new UnaryExpression(ANY_ELEMENT_TRUE, expression);
227 }
228
229 /**
230 * Returns a {@link NaryExpression} {@value #COMPARE} expression.
231 *
232 * @param lhs
233 * The left hand side of the operation.
234 * @param rhs
235 * The left hand side of the operation.
236 * @return The {@link NaryExpression} {@value #COMPARE} expression.
237 */
238 public static NaryExpression cmp(final Expression lhs, final Expression rhs) {
239 return new NaryExpression(COMPARE, lhs, rhs);
240 }
241
242 /**
243 * Returns a {@link NaryExpression} {@value #CONCATENATE} expression.
244 *
245 * @param expression
246 * The string expressions for the operator.
247 * @return The {@link NaryExpression} {@value #CONCATENATE} expression.
248 *
249 * @since MongoDB 2.4
250 */
251 public static NaryExpression concatenate(final Expression... expression) {
252 return new NaryExpression(CONCATENATE, expression);
253 }
254
255 /**
256 * Returns a {@link NaryExpression} {@value #CONDITION} expression.
257 *
258 * @param test
259 * The conditions test.
260 * @param trueResult
261 * The result if the test is true.
262 * @param falseResult
263 * The result if the test is false.
264 * @return The {@link NaryExpression} {@value #CONDITION} expression.
265 */
266 public static NaryExpression cond(final Expression test,
267 final Expression trueResult, final Expression falseResult) {
268 return new NaryExpression(CONDITION, test, trueResult, falseResult);
269 }
270
271 /**
272 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
273 *
274 * @param value
275 * The constants value.
276 * @return The {@link Constant} expression.
277 */
278 public static Constant constant(final boolean value) {
279 return new Constant(new BooleanElement("", value));
280 }
281
282 /**
283 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
284 *
285 * @param value
286 * The constants value.
287 * @return The {@link Constant} expression.
288 */
289 public static Constant constant(final Date value) {
290 return constantTimestamp(value.getTime());
291 }
292
293 /**
294 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
295 *
296 * @param value
297 * The constants value.
298 * @return The {@link Constant} expression.
299 */
300 public static Constant constant(final double value) {
301 return new Constant(new DoubleElement("", value));
302 }
303
304 /**
305 * Returns a {@link Constant} expression wrapping the provided
306 * <tt>element</tt>. This method is intended mainly for wrapping arrays
307 * using the {@link BuilderFactory#a} method.<blockquote>
308 *
309 * <pre>
310 * <code>
311 * import static {@link BuilderFactory#a com.allanbank.mongodb.bson.builder.BuilderFactory.a}
312 * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant}
313 *
314 * constant( a( "This", "is", "an", "array" ) );
315 * </code>
316 * </pre>
317 *
318 * </blockquote>
319 *
320 * @param element
321 * The element value.
322 * @return The {@link Constant} expression.
323 */
324 public static Expression constant(final Element element) {
325 return new Constant(element);
326 }
327
328 /**
329 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
330 *
331 * @param value
332 * The constants value.
333 * @return The {@link Constant} expression.
334 */
335 public static Constant constant(final int value) {
336 return new Constant(new IntegerElement("", value));
337 }
338
339 /**
340 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
341 *
342 * @param value
343 * The constants value.
344 * @return The {@link Constant} expression.
345 */
346 public static Constant constant(final long value) {
347 return new Constant(new LongElement("", value));
348 }
349
350 /**
351 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
352 *
353 * @param value
354 * The constants value.
355 * @return The {@link Constant} expression.
356 */
357 public static Constant constant(final ObjectId value) {
358 return new Constant(new ObjectIdElement("", value));
359 }
360
361 /**
362 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
363 *
364 * @param value
365 * The constants value.
366 * @return The {@link Constant} expression.
367 */
368 public static Constant constant(final Pattern value) {
369 return new Constant(new RegularExpressionElement("", value));
370 }
371
372 /**
373 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
374 *
375 * @param value
376 * The constants value.
377 * @return The {@link Constant} expression.
378 */
379 public static Constant constant(final String value) {
380 return new Constant(new StringElement("", value));
381 }
382
383 /**
384 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
385 *
386 * @param value
387 * The constants value.
388 * @return The {@link Constant} expression.
389 */
390 public static Constant constantMongoTimestamp(final long value) {
391 return new Constant(new MongoTimestampElement("", value));
392 }
393
394 /**
395 * Returns a {@link Constant} expression with the provided <tt>value</tt>.
396 *
397 * @param value
398 * The constants value.
399 * @return The {@link Constant} expression.
400 */
401 public static Constant constantTimestamp(final long value) {
402 return new Constant(new TimestampElement("", value));
403 }
404
405 /**
406 * Returns a {@link UnaryExpression} {@value #DAY_OF_MONTH} expression.
407 *
408 * @param expression
409 * The date for the operator.
410 * @return The {@link UnaryExpression} {@value #DAY_OF_MONTH} expression.
411 */
412 public static UnaryExpression dayOfMonth(final Expression expression) {
413 return new UnaryExpression(DAY_OF_MONTH, expression);
414 }
415
416 /**
417 * Returns a {@link UnaryExpression} {@value #DAY_OF_WEEK} expression.
418 *
419 * @param expression
420 * The date for the operator.
421 * @return The {@link UnaryExpression} {@value #DAY_OF_WEEK} expression.
422 */
423 public static UnaryExpression dayOfWeek(final Expression expression) {
424 return new UnaryExpression(DAY_OF_WEEK, expression);
425 }
426
427 /**
428 * Returns a {@link UnaryExpression} {@value #DAY_OF_YEAR} expression.
429 *
430 * @param expression
431 * The date for the operator.
432 * @return The {@link UnaryExpression} {@value #DAY_OF_YEAR} expression.
433 */
434 public static UnaryExpression dayOfYear(final Expression expression) {
435 return new UnaryExpression(DAY_OF_YEAR, expression);
436 }
437
438 /**
439 * Returns a {@link NaryExpression} {@value #DIVIDE} expression.
440 *
441 * @param numerator
442 * The numerator of the division.
443 * @param denominator
444 * The denominator of the division.
445 * @return The {@link NaryExpression} {@value #DIVIDE} expression.
446 */
447 public static NaryExpression divide(final Expression numerator,
448 final Expression denominator) {
449 return new NaryExpression(DIVIDE, numerator, denominator);
450 }
451
452 /**
453 * Returns a {@link NaryExpression} {@value #EQUAL} expression.
454 *
455 * @param lhs
456 * The left hand side of the equals.
457 * @param rhs
458 * The right hand side of the equals.
459 * @return The {@link NaryExpression} {@value #EQUAL} expression.
460 */
461 public static NaryExpression eq(final Expression lhs, final Expression rhs) {
462 return new NaryExpression(EQUAL, lhs, rhs);
463 }
464
465 /**
466 * Returns a {@link Constant} expression with the provided
467 * <tt>fieldName</tt>.
468 * <p>
469 * Prepends a {@code $} to the field name if not already present.
470 * </p>
471 * <blockquote>
472 *
473 * <pre>
474 * <code>
475 * Constant field = Expressions.field("field");
476 *
477 * // Produces output:
478 * // $field
479 * System.out.println(field);
480 * </code>
481 * </pre>
482 *
483 * </blockquote>
484 *
485 * @param fieldName
486 * The name of the field.
487 * @return The {@link Constant} expression.
488 */
489 public static Constant field(final String fieldName) {
490 if (fieldName.startsWith("$")) {
491 return new Constant(new StringElement("", fieldName));
492 }
493 return new Constant(new StringElement("", "$" + fieldName));
494 }
495
496 /**
497 * Returns a {@link NaryExpression} {@value #GREATER_THAN} expression.
498 *
499 * @param lhs
500 * The left hand side of the comparison.
501 * @param rhs
502 * The right hand side of the comparison.
503 * @return The {@link NaryExpression} {@value #GREATER_THAN} expression.
504 */
505 public static NaryExpression gt(final Expression lhs, final Expression rhs) {
506 return new NaryExpression(GREATER_THAN, lhs, rhs);
507 }
508
509 /**
510 * Returns a {@link NaryExpression} {@value #GREATER_THAN_OR_EQUAL}
511 * expression.
512 *
513 * @param lhs
514 * The left hand side of the comparison.
515 * @param rhs
516 * The right hand side of the comparison.
517 * @return The {@link NaryExpression} {@value #GREATER_THAN_OR_EQUAL}
518 * expression.
519 */
520 public static NaryExpression gte(final Expression lhs, final Expression rhs) {
521 return new NaryExpression(GREATER_THAN_OR_EQUAL, lhs, rhs);
522 }
523
524 /**
525 * Returns a {@link UnaryExpression} {@value #HOUR} expression.
526 *
527 * @param expression
528 * The date for the operator.
529 * @return The {@link UnaryExpression} {@value #HOUR} expression.
530 */
531 public static UnaryExpression hour(final Expression expression) {
532 return new UnaryExpression(HOUR, expression);
533 }
534
535 /**
536 * Returns a {@link NaryExpression} {@value #IF_NULL} expression.
537 *
538 * @param first
539 * The first expression.
540 * @param second
541 * The second expression.
542 * @return The {@link NaryExpression} {@value #IF_NULL} expression.
543 */
544 public static NaryExpression ifNull(final Expression first,
545 final Expression second) {
546 return new NaryExpression(IF_NULL, first, second);
547 }
548
549 /**
550 * Creates a {@code $let} expression with the provided variables and
551 * {@code in} expression.
552 * <p>
553 * Here is the <a href=
554 * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
555 * <code>let</code> expression's documentation</a> aggregation pipe line
556 * using this helper class. <blockquote>
557 *
558 * <pre>
559 * <code>
560 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
561 * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
562 * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
563 * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
564 * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
565 * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
566 * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
567 * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
568 * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
569 *
570 * Aggregate.Builder aggregate = Aggregate.builder();
571 *
572 * // $project: {
573 * // finalTotal: {
574 * // $let: {
575 * // vars: {
576 * // total: { $add: [ '$price', '$tax' ] },
577 * // discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
578 * // },
579 * // in: { $multiply: [ "$$total", "$$discounted" ] }
580 * // }
581 * // }
582 * // }
583 * final Aggregate.Builder aggregation = Aggregate.builder();
584 * aggregation.project(
585 * include(),
586 * set("finalTotal",
587 * let(
588 * multiply(var("total"), var("discounted"))
589 * set("total", add(field("price"), field("tax"))),
590 * set("discounted",
591 * cond(field("applyDiscount"), constant(0.9),
592 * constant(1))))));
593 *
594 * // Aggregation Pipeline : '$pipeline' : [
595 * // {
596 * // '$project' : {
597 * // finalTotal : {
598 * // '$let' : {
599 * // vars : {
600 * // total : {
601 * // '$add' : [
602 * // '$price',
603 * // '$tax'
604 * // ]
605 * // },
606 * // discounted : {
607 * // '$cond' : [
608 * // '$applyDiscount',
609 * // 0.9,
610 * // 1
611 * // ]
612 * // }
613 * // },
614 * // in : {
615 * // '$multiply' : [
616 * // '$$total',
617 * // '$$discounted'
618 * // ]
619 * // }
620 * // }
621 * // }
622 * // }
623 * // }
624 * // ]
625 * System.out.println("Aggregation Pipeline : " + aggregation);
626 * </code>
627 * </pre>
628 *
629 * </blockquote>
630 *
631 * @param inExpression
632 * The expression to be evaluated with the variables within the
633 * {@code $let} expression.
634 * @param variables
635 * The variables for the {@code $let} expression.
636 * @return The Element to set the value to the document.
637 */
638 public static UnaryExpression let(final Expression inExpression,
639 final Element... variables) {
640 return let(Arrays.asList(variables), inExpression);
641 }
642
643 /**
644 * Creates a {@code $let} expression with the provided variables and
645 * {@code in} expression.
646 * <p>
647 * Here is the <a href=
648 * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
649 * <code>let</code> expression's documentation</a> aggregation pipe line
650 * using this helper class. <blockquote>
651 *
652 * <pre>
653 * <code>
654 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
655 * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
656 * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
657 * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
658 * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
659 * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
660 * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
661 * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
662 * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
663 *
664 * Aggregate.Builder aggregate = Aggregate.builder();
665 *
666 * // $project: {
667 * // finalTotal: {
668 * // $let: {
669 * // vars: {
670 * // total: { $add: [ '$price', '$tax' ] },
671 * // discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
672 * // },
673 * // in: { $multiply: [ "$$total", "$$discounted" ] }
674 * // }
675 * // }
676 * // }
677 * final Aggregate.Builder aggregation = Aggregate.builder();
678 * aggregation.project(
679 * include(),
680 * set("finalTotal",
681 * let(
682 * Arrays.asList(
683 * set("total", add(field("price"), field("tax"))),
684 * set("discounted",
685 * cond(field("applyDiscount"), constant(0.9),
686 * constant(1))))
687 * multiply(var("total"), var("discounted")))));
688 *
689 * // Aggregation Pipeline : '$pipeline' : [
690 * // {
691 * // '$project' : {
692 * // finalTotal : {
693 * // '$let' : {
694 * // vars : {
695 * // total : {
696 * // '$add' : [
697 * // '$price',
698 * // '$tax'
699 * // ]
700 * // },
701 * // discounted : {
702 * // '$cond' : [
703 * // '$applyDiscount',
704 * // 0.9,
705 * // 1
706 * // ]
707 * // }
708 * // },
709 * // in : {
710 * // '$multiply' : [
711 * // '$$total',
712 * // '$$discounted'
713 * // ]
714 * // }
715 * // }
716 * // }
717 * // }
718 * // }
719 * // ]
720 * System.out.println("Aggregation Pipeline : " + aggregation);
721 * </code>
722 * </pre>
723 *
724 * </blockquote>
725 *
726 * @param variables
727 * The variables for the {@code $let} expression.
728 * @param inExpression
729 * The expression to be evaluated with the variables within the
730 * {@code $let} expression.
731 * @return The Element to set the value to the document.
732 */
733 public static UnaryExpression let(final List<Element> variables,
734 final Expression inExpression) {
735 final DocumentAssignable letDocument = d(new DocumentElement("vars",
736 variables), inExpression.toElement("in"));
737
738 return new UnaryExpression("$let", new Constant(new DocumentElement(
739 "$let", letDocument.asDocument())));
740 }
741
742 /**
743 * Starts the creation of a {@code $let} expression. The returned
744 * {@link LetBuilder} can be used to add additional variables before setting
745 * the {@link LetBuilder#in final expression} to evaluate.
746 * <p>
747 * Here is the <a href=
748 * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
749 * <code>let</code> expression's documentation</a> aggregation pipe line
750 * using this helper class. <blockquote>
751 *
752 * <pre>
753 * <code>
754 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
755 * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
756 * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
757 * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
758 * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
759 * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
760 * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
761 * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
762 * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
763 *
764 * Aggregate.Builder aggregate = Aggregate.builder();
765 *
766 * // $project: {
767 * // finalTotal: {
768 * // $let: {
769 * // vars: {
770 * // total: { $add: [ '$price', '$tax' ] },
771 * // discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
772 * // },
773 * // in: { $multiply: [ "$$total", "$$discounted" ] }
774 * // }
775 * // }
776 * // }
777 * final Aggregate.Builder aggregation = Aggregate.builder();
778 * aggregation.project(
779 * include(),
780 * set("finalTotal",
781 * let("total", add(field("price"), field("tax")))
782 * .let("discounted", cond(field("applyDiscount"),
783 * constant(0.9),
784 * constant(1)))
785 * .in(multiply(var("total"), var("discounted")))));
786 *
787 * // Aggregation Pipeline : '$pipeline' : [
788 * // {
789 * // '$project' : {
790 * // finalTotal : {
791 * // '$let' : {
792 * // vars : {
793 * // total : {
794 * // '$add' : [
795 * // '$price',
796 * // '$tax'
797 * // ]
798 * // },
799 * // discounted : {
800 * // '$cond' : [
801 * // '$applyDiscount',
802 * // 0.9,
803 * // 1
804 * // ]
805 * // }
806 * // },
807 * // in : {
808 * // '$multiply' : [
809 * // '$$total',
810 * // '$$discounted'
811 * // ]
812 * // }
813 * // }
814 * // }
815 * // }
816 * // }
817 * // ]
818 * System.out.println("Aggregation Pipeline : " + aggregation);
819 * </code>
820 * </pre>
821 *
822 * </blockquote>
823 *
824 * @param name
825 * The name of the first field to set.
826 * @param document
827 * The document to set the first field value to.
828 * @return The Element to set the value to the document.
829 */
830 public static LetBuilder let(final String name,
831 final DocumentAssignable document) {
832 return new LetBuilder(new DocumentElement(name, document.asDocument()));
833 }
834
835 /**
836 * Starts the creation of a {@code $let} expression. The returned
837 * {@link LetBuilder} can be used to add additional variables before setting
838 * the {@link LetBuilder#in final expression} to evaluate.
839 * <p>
840 * Here is the <a href=
841 * "http://docs.mongodb.org/master/reference/operator/aggregation/let/">
842 * <code>let</code> expression's documentation</a> aggregation pipe line
843 * using this helper class. <blockquote>
844 *
845 * <pre>
846 * <code>
847 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
848 * import static {@link Expressions#add com.allanbank.mongodb.builder.expression.Expressions.add};
849 * import static {@link Expressions#cond com.allanbank.mongodb.builder.expression.Expressions.cond};
850 * import static {@link Expressions#constant com.allanbank.mongodb.builder.expression.Expressions.constant};
851 * import static {@link Expressions#field com.allanbank.mongodb.builder.expression.Expressions.field};
852 * import static {@link Expressions#let com.allanbank.mongodb.builder.expression.Expressions.let};
853 * import static {@link Expressions#multiply com.allanbank.mongodb.builder.expression.Expressions.multiply};
854 * import static {@link Expressions#set com.allanbank.mongodb.builder.expression.Expressions.set};
855 * import static {@link Expressions#var com.allanbank.mongodb.builder.expression.Expressions.var};
856 *
857 * Aggregate.Builder aggregate = Aggregate.builder();
858 *
859 * // $project: {
860 * // finalTotal: {
861 * // $let: {
862 * // vars: {
863 * // total: { $add: [ '$price', '$tax' ] },
864 * // discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
865 * // },
866 * // in: { $multiply: [ "$$total", "$$discounted" ] }
867 * // }
868 * // }
869 * // }
870 * final Aggregate.Builder aggregation = Aggregate.builder();
871 * aggregation.project(
872 * include(),
873 * set("finalTotal",
874 * let("total", add(field("price"), field("tax")))
875 * .let("discounted", cond(field("applyDiscount"),
876 * constant(0.9),
877 * constant(1)))
878 * .in(multiply(var("total"), var("discounted")))));
879 *
880 * // Aggregation Pipeline : '$pipeline' : [
881 * // {
882 * // '$project' : {
883 * // finalTotal : {
884 * // '$let' : {
885 * // vars : {
886 * // total : {
887 * // '$add' : [
888 * // '$price',
889 * // '$tax'
890 * // ]
891 * // },
892 * // discounted : {
893 * // '$cond' : [
894 * // '$applyDiscount',
895 * // 0.9,
896 * // 1
897 * // ]
898 * // }
899 * // },
900 * // in : {
901 * // '$multiply' : [
902 * // '$$total',
903 * // '$$discounted'
904 * // ]
905 * // }
906 * // }
907 * // }
908 * // }
909 * // }
910 * // ]
911 * System.out.println("Aggregation Pipeline : " + aggregation);
912 * </code>
913 * </pre>
914 *
915 * </blockquote>
916 *
917 * @param name
918 * The name of the field to set.
919 * @param expression
920 * The expression to compute the value for the first field.
921 * @return The Element to set the value to the expression.
922 */
923 public static LetBuilder let(final String name, final Expression expression) {
924 return new LetBuilder(expression.toElement(name));
925 }
926
927 /**
928 * Returns a {@link Constant} expression wrapping the <tt>value</tt> in a
929 * {@value #LITERAL} sub-document.
930 *
931 * @param value
932 * The constants value.
933 * @return The {@link Constant} expression.
934 */
935 public static Constant literal(final String value) {
936 return new Constant(new DocumentElement("", new StringElement(
937 "$literal", value)));
938 }
939
940 /**
941 * Returns a {@link NaryExpression} {@value #LESS_THAN} expression.
942 *
943 * @param lhs
944 * The left hand side of the comparison.
945 * @param rhs
946 * The right hand side of the comparison.
947 * @return The {@link NaryExpression} {@value #LESS_THAN} expression.
948 */
949 public static NaryExpression lt(final Expression lhs, final Expression rhs) {
950 return new NaryExpression(LESS_THAN, lhs, rhs);
951 }
952
953 /**
954 * Returns a {@link NaryExpression} {@value #LESS_THAN_OR_EQUAL} expression.
955 *
956 * @param lhs
957 * The left hand side of the comparison.
958 * @param rhs
959 * The right hand side of the comparison.
960 * @return The {@link NaryExpression} {@value #LESS_THAN} expression.
961 */
962 public static NaryExpression lte(final Expression lhs, final Expression rhs) {
963 return new NaryExpression(LESS_THAN_OR_EQUAL, lhs, rhs);
964 }
965
966 /**
967 * Returns a {@link UnaryExpression} expression for the {@code $map}
968 * operation.
969 * <p>
970 * Prepends a {@code $} to the {@code inputField} name if not already
971 * present.
972 * </p>
973 * <p>
974 * Here is the <a href=
975 * "http://docs.mongodb.org/master/reference/operator/aggregation/map/">
976 * <code>map</code> expression's documentation</a> aggregation pipe line
977 * using this helper class. <blockquote>
978 *
979 * <pre>
980 * <code>
981 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
982 * import static {@link Expressions#map(String,String,Expression) com.allanbank.mongodb.builder.expression.Expressions.map};
983 * import static {@link Expressions#set(String,Expression) com.allanbank.mongodb.builder.expression.Expressions.set};
984 * import static {@link Expressions#add(Expression...) com.allanbank.mongodb.builder.expression.Expressions.add};
985 * import static {@link Expressions#var(String) com.allanbank.mongodb.builder.expression.Expressions.var};
986 * import static {@link Expressions#constant(int) com.allanbank.mongodb.builder.expression.Expressions.constant};
987 *
988 * Aggregate.Builder aggregate = Aggregate.builder();
989 *
990 * // { $project: { adjustments: { $map: { input: "$skews",
991 * // as: "adj",
992 * // in: { $add: [ "$$adj", 12 ] } } } } }
993 * aggregate.project(
994 * include(),
995 * set( "adjustments",
996 * map("skews").as("adj").in( add( var("adj"), constant(12) ) ) ) );
997 *
998 * // Produces output:
999 * // {
1000 * // '$project' : {
1001 * // adjustments : {
1002 * // '$map' {
1003 * // input : '$skews',
1004 * // as : 'adj',
1005 * // in : {
1006 * // '$add' : [
1007 * // '$$adj',
1008 * // 12
1009 * // ]
1010 * // }
1011 * // }
1012 * // }
1013 * // }
1014 * // }
1015 * System.out.println(aggregate);
1016 * </code>
1017 * </pre>
1018 *
1019 * </blockquote>
1020 *
1021 * @param inputField
1022 * The name of the {@code input} field. The map operation
1023 * expression.
1024 * @return The first stage of the {@code $map} expression construction.
1025 *
1026 * @see <a
1027 * href="http://docs.mongodb.org/master/reference/operator/aggregation/map/"><code>map</code>
1028 * expression documentation</a>
1029 */
1030 public static MapStage1 map(final String inputField) {
1031 return new MapStage1(inputField);
1032 }
1033
1034 /**
1035 * Returns a {@link UnaryExpression} expression for the {@code $map}
1036 * operation.
1037 * <p>
1038 * Prepends a {@code $} to the {@code inputField} name if not already
1039 * present.
1040 * </p>
1041 * <p>
1042 * Here is the <a href=
1043 * "http://docs.mongodb.org/master/reference/operator/aggregation/map/">
1044 * <code>map</code> expression's documentation</a> aggregation pipe line
1045 * using this helper class. <blockquote>
1046 *
1047 * <pre>
1048 * <code>
1049 * import static com.allanbank.mongodb.builder.AggregationProjectFields.include;
1050 * import static {@link Expressions#map(String,String,Expression) com.allanbank.mongodb.builder.expression.Expressions.map};
1051 * import static {@link Expressions#set(String,Expression) com.allanbank.mongodb.builder.expression.Expressions.set};
1052 * import static {@link Expressions#add(Expression...) com.allanbank.mongodb.builder.expression.Expressions.add};
1053 * import static {@link Expressions#var(String) com.allanbank.mongodb.builder.expression.Expressions.var};
1054 * import static {@link Expressions#constant(int) com.allanbank.mongodb.builder.expression.Expressions.constant};
1055 *
1056 * Aggregate.Builder aggregate = Aggregate.builder();
1057 *
1058 * // { $project: { adjustments: { $map: { input: "$skews",
1059 * // as: "adj",
1060 * // in: { $add: [ "$$adj", 12 ] } } } } }
1061 * aggregate.project(
1062 * include(),
1063 * set( "adjustments",
1064 * map( "skews", "adj",
1065 * add( var("adj"), constant(12) ) ) ) );
1066 *
1067 * // Produces output:
1068 * // {
1069 * // '$project' : {
1070 * // adjustments : {
1071 * // '$map' {
1072 * // input : '$skews',
1073 * // as : 'adj',
1074 * // in : {
1075 * // '$add' : [
1076 * // '$$adj',
1077 * // 12
1078 * // ]
1079 * // }
1080 * // }
1081 * // }
1082 * // }
1083 * // }
1084 * System.out.println(aggregate);
1085 * </code>
1086 * </pre>
1087 *
1088 * </blockquote>
1089 *
1090 * @param inputField
1091 * The name of the {@code input} field.
1092 * @param variableName
1093 * The name of the {@code as} variable.
1094 * @param mapOperation
1095 * The map operation expression.
1096 * @return The {@link UnaryExpression} expression.
1097 *
1098 * @see <a
1099 * href="http://docs.mongodb.org/master/reference/operator/aggregation/map/"><code>map</code>
1100 * expression documentation</a>
1101 */
1102 public static UnaryExpression map(final String inputField,
1103 final String variableName, final Expression mapOperation) {
1104
1105 final DocumentAssignable mapDocument = d(
1106 field(inputField).toElement("input"), constant(variableName)
1107 .toElement("as"), mapOperation.toElement("in"));
1108
1109 return new UnaryExpression("$map", new Constant(new DocumentElement(
1110 "$map", mapDocument.asDocument())));
1111 }
1112
1113 /**
1114 * Returns a {@link UnaryExpression} {@value #MILLISECOND} expression.
1115 *
1116 * @param expression
1117 * The date for the operator.
1118 * @return The {@link UnaryExpression} {@value #MILLISECOND} expression.
1119 */
1120 public static UnaryExpression millisecond(final Expression expression) {
1121 return new UnaryExpression(MILLISECOND, expression);
1122 }
1123
1124 /**
1125 * Returns a {@link UnaryExpression} {@value #MINUTE} expression.
1126 *
1127 * @param expression
1128 * The date for the operator.
1129 * @return The {@link UnaryExpression} {@value #MINUTE} expression.
1130 */
1131 public static UnaryExpression minute(final Expression expression) {
1132 return new UnaryExpression(MINUTE, expression);
1133 }
1134
1135 /**
1136 * Returns a {@link NaryExpression} {@value #MODULO} expression.
1137 *
1138 * @param numerator
1139 * The numerator of the modulo operation.
1140 * @param denominator
1141 * The denominator of the modulo operation.
1142 * @return The {@link NaryExpression} {@value #MODULO} expression.
1143 */
1144 public static NaryExpression mod(final Expression numerator,
1145 final Expression denominator) {
1146 return new NaryExpression(MODULO, numerator, denominator);
1147 }
1148
1149 /**
1150 * Returns a {@link UnaryExpression} {@value #MONTH} expression.
1151 *
1152 * @param expression
1153 * The date for the operator.
1154 * @return The {@link UnaryExpression} {@value #MONTH} expression.
1155 */
1156 public static UnaryExpression month(final Expression expression) {
1157 return new UnaryExpression(MONTH, expression);
1158 }
1159
1160 /**
1161 * Returns a {@link NaryExpression} {@value #MULTIPLY} expression.
1162 *
1163 * @param lhs
1164 * The left hand side of the operator.
1165 * @param rhs
1166 * The right hand side of the operator.
1167 * @return The {@link NaryExpression} {@value #MULTIPLY} expression.
1168 */
1169 public static NaryExpression multiply(final Expression lhs,
1170 final Expression rhs) {
1171 return new NaryExpression(MULTIPLY, lhs, rhs);
1172 }
1173
1174 /**
1175 * Returns a {@link NaryExpression} {@value #NOT_EQUAL} expression.
1176 *
1177 * @param lhs
1178 * The left hand side of the comparison.
1179 * @param rhs
1180 * The right hand side of the comparison.
1181 * @return The {@link NaryExpression} {@value #NOT_EQUAL} expression.
1182 */
1183 public static NaryExpression ne(final Expression lhs, final Expression rhs) {
1184 return new NaryExpression(NOT_EQUAL, lhs, rhs);
1185 }
1186
1187 /**
1188 * Returns a {@link UnaryExpression} {@value #NOT} expression.
1189 *
1190 * @param expression
1191 * The sub expressions for the $not.
1192 * @return The {@link UnaryExpression} {@value #NOT} expression.
1193 */
1194 public static UnaryExpression not(final Expression expression) {
1195 return new UnaryExpression(NOT, expression);
1196 }
1197
1198 /**
1199 * Returns a <code>null</code> {@link Constant} expression.
1200 *
1201 * @return The {@link Constant} expression.
1202 */
1203 public static Constant nullConstant() {
1204 return new Constant(new NullElement(""));
1205 }
1206
1207 /**
1208 * Returns an {@link NaryExpression} {@value #OR} expression.
1209 *
1210 * @param expressions
1211 * The sub-expressions.
1212 * @return The {@link NaryExpression} {@value #OR} expression.
1213 */
1214 public static NaryExpression or(final Expression... expressions) {
1215 return new NaryExpression(OR, expressions);
1216 }
1217
1218 /**
1219 * Returns a {@link UnaryExpression} {@value #SECOND} expression.
1220 *
1221 * @param expression
1222 * The date for the operator.
1223 * @return The {@link UnaryExpression} {@value #SECOND} expression.
1224 */
1225 public static UnaryExpression second(final Expression expression) {
1226 return new UnaryExpression(SECOND, expression);
1227 }
1228
1229 /**
1230 * Returns an element to set the value to.
1231 *
1232 * @param name
1233 * The name of the field to set.
1234 * @param document
1235 * The document to set the document to.
1236 * @return The Element to set the value to the document.
1237 */
1238 public static Element set(final String name,
1239 final DocumentAssignable document) {
1240 return new DocumentElement(name, document.asDocument());
1241 }
1242
1243 /**
1244 * Returns an element to set the value to.
1245 *
1246 * @param name
1247 * The name of the field to set.
1248 * @param expression
1249 * The expression to compute the value for the field.
1250 * @return The Element to set the value to the expression.
1251 */
1252 public static Element set(final String name, final Expression expression) {
1253 return expression.toElement(name);
1254 }
1255
1256 /**
1257 * Returns a {@link NaryExpression} {@value #SET_DIFFERENCE} expression.
1258 *
1259 * @param lhs
1260 * The expression that will be evaluated to create the first set.
1261 * @param rhs
1262 * The expression that will be evaluated to create the second
1263 * set.
1264 * @return The {@link NaryExpression} {@value #SET_DIFFERENCE} expression.
1265 */
1266 public static NaryExpression setDifference(final Expression lhs,
1267 final Expression rhs) {
1268 return new NaryExpression(SET_DIFFERENCE, lhs, rhs);
1269 }
1270
1271 /**
1272 * Returns a {@link NaryExpression} {@value #SET_EQUALS} expression.
1273 *
1274 * @param lhs
1275 * The expression that will be evaluated to create the first set.
1276 * @param rhs
1277 * The expression that will be evaluated to create the second
1278 * set.
1279 * @return The {@link NaryExpression} {@value #SET_EQUALS} expression.
1280 */
1281 public static NaryExpression setEquals(final Expression lhs,
1282 final Expression rhs) {
1283 return new NaryExpression(SET_EQUALS, lhs, rhs);
1284 }
1285
1286 /**
1287 * Returns a {@link NaryExpression} {@value #SET_INTERSECTION} expression.
1288 *
1289 * @param lhs
1290 * The expression that will be evaluated to create the first set.
1291 * @param rhs
1292 * The expression that will be evaluated to create the second
1293 * set.
1294 * @return The {@link NaryExpression} {@value #SET_INTERSECTION} expression.
1295 */
1296 public static NaryExpression setIntersection(final Expression lhs,
1297 final Expression rhs) {
1298 return new NaryExpression(SET_INTERSECTION, lhs, rhs);
1299 }
1300
1301 /**
1302 * Returns a {@link NaryExpression} {@value #SET_IS_SUBSET} expression.
1303 *
1304 * @param subSet
1305 * The expression that will be tested to see if it is a subset of
1306 * the {@code completeSet}.
1307 * @param completeSet
1308 * The expression that will be evaluated to construct the
1309 * complete set of values.
1310 * @return The {@link NaryExpression} {@value #SET_IS_SUBSET} expression.
1311 */
1312 public static NaryExpression setIsSubset(final Expression subSet,
1313 final Expression completeSet) {
1314 return new NaryExpression(SET_IS_SUBSET, subSet, completeSet);
1315 }
1316
1317 /**
1318 * Returns a {@link NaryExpression} {@value #SET_UNION} expression.
1319 *
1320 * @param lhs
1321 * The expression that will be evaluated to create the first set.
1322 * @param rhs
1323 * The expression that will be evaluated to create the second
1324 * set.
1325 * @return The {@link NaryExpression} {@value #SET_UNION} expression.
1326 */
1327 public static NaryExpression setUnion(final Expression lhs,
1328 final Expression rhs) {
1329 return new NaryExpression(SET_UNION, lhs, rhs);
1330 }
1331
1332 /**
1333 * Returns a {@link UnaryExpression} {@value #SIZE} expression.
1334 *
1335 * @param expression
1336 * The expression that will be evaluated to create the set to
1337 * inspect for a true element.
1338 * @return The {@link UnaryExpression} {@value #SIZE} expression.
1339 */
1340 public static UnaryExpression size(final Expression expression) {
1341 return new UnaryExpression(SIZE, expression);
1342 }
1343
1344 /**
1345 * Returns a {@link NaryExpression}
1346 * {@value #STRING_CASE_INSENSITIVE_COMPARE} expression.
1347 *
1348 * @param lhs
1349 * The left hand side of the comparison.
1350 * @param rhs
1351 * The right hand side of the comparison.
1352 * @return The {@link NaryExpression}
1353 * {@value #STRING_CASE_INSENSITIVE_COMPARE} expression.
1354 */
1355 public static NaryExpression strcasecmp(final Expression lhs,
1356 final Expression rhs) {
1357 return new NaryExpression(STRING_CASE_INSENSITIVE_COMPARE, lhs, rhs);
1358 }
1359
1360 /**
1361 * Returns a {@link NaryExpression} {@value #SUB_STRING} expression.
1362 *
1363 * @param string
1364 * The string to pull a sub-string from.
1365 * @param skip
1366 * The number of characters to skip in the string.
1367 * @param length
1368 * The length of the string to extract.
1369 * @return The {@link NaryExpression} {@value #SUB_STRING} expression.
1370 */
1371 public static NaryExpression substr(final Expression string,
1372 final Expression skip, final Expression length) {
1373 return new NaryExpression(SUB_STRING, string, skip, length);
1374 }
1375
1376 /**
1377 * Returns a {@link NaryExpression} {@value #SUBTRACT} expression.
1378 *
1379 * @param lhs
1380 * The left hand side of the operator.
1381 * @param rhs
1382 * The right hand side of the operator.
1383 * @return The {@link NaryExpression} {@value #SUBTRACT} expression.
1384 */
1385 public static NaryExpression subtract(final Expression lhs,
1386 final Expression rhs) {
1387 return new NaryExpression(SUBTRACT, lhs, rhs);
1388 }
1389
1390 /**
1391 * Returns a {@link UnaryExpression} {@value #TO_LOWER} expression.
1392 *
1393 * @param string
1394 * The string to modify.
1395 * @return The {@link UnaryExpression} {@value #TO_LOWER} expression.
1396 */
1397 public static UnaryExpression toLower(final Expression string) {
1398 return new UnaryExpression(TO_LOWER, string);
1399 }
1400
1401 /**
1402 * Returns a {@link UnaryExpression} {@value #TO_UPPER} expression.
1403 *
1404 * @param string
1405 * The string to modify.
1406 * @return The {@link UnaryExpression} {@value #TO_UPPER} expression.
1407 */
1408 public static UnaryExpression toUpper(final Expression string) {
1409 return new UnaryExpression(TO_UPPER, string);
1410 }
1411
1412 /**
1413 * Returns a {@link Constant} expression with the provided
1414 * <tt>variableName</tt>. See the {@link #let $let} and {@link #map $map}
1415 * expressions for example usage.
1416 * <p>
1417 * Prepends a {@code $$} to the variable name if not already present.
1418 * </p>
1419 * <blockquote>
1420 *
1421 * <pre>
1422 * <code>
1423 * Constant variable = Expressions.var("variable");
1424 *
1425 * // Produces output:
1426 * // $$variable
1427 * System.out.println(variable);
1428 * </code>
1429 * </pre>
1430 *
1431 * </blockquote>
1432 *
1433 * @param variableName
1434 * The name of the field.
1435 * @return The {@link Constant} expression.
1436 */
1437 public static Constant var(final String variableName) {
1438
1439 Constant result;
1440 if (variableName.startsWith("$$")) {
1441 result = new Constant(new StringElement("", variableName));
1442 }
1443 else if (variableName.startsWith("$")) {
1444 result = new Constant(new StringElement("", "$" + variableName));
1445 }
1446 else {
1447 result = new Constant(new StringElement("", "$$" + variableName));
1448 }
1449 return result;
1450 }
1451
1452 /**
1453 * Returns a {@link UnaryExpression} {@value #WEEK} expression.
1454 *
1455 * @param expression
1456 * The date for the operator.
1457 * @return The {@link UnaryExpression} {@value #WEEK} expression.
1458 */
1459 public static UnaryExpression week(final Expression expression) {
1460 return new UnaryExpression(WEEK, expression);
1461 }
1462
1463 /**
1464 * Returns a {@link UnaryExpression} {@value #YEAR} expression.
1465 *
1466 * @param expression
1467 * The date for the operator.
1468 * @return The {@link UnaryExpression} {@value #YEAR} expression.
1469 */
1470 public static UnaryExpression year(final Expression expression) {
1471 return new UnaryExpression(YEAR, expression);
1472 }
1473
1474 /**
1475 * Creates a new Expressions.
1476 */
1477 private Expressions() {
1478 }
1479 }