Browse Source
Refactored to multiple smaller Aggregation Operator classes reflecting the grouping (array operators, string operators,…) predefined by MongoDB. Original pull request: #429.pull/692/head
30 changed files with 9141 additions and 8730 deletions
@ -0,0 +1,149 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.bson.Document; |
||||||
|
import org.springframework.util.ObjectUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
abstract class AbstractAggregationExpression implements AggregationExpression { |
||||||
|
|
||||||
|
private final Object value; |
||||||
|
|
||||||
|
protected AbstractAggregationExpression(Object value) { |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(AggregationOperationContext context) { |
||||||
|
return toDocument(this.value, context); |
||||||
|
} |
||||||
|
|
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
Object valueToUse; |
||||||
|
if (value instanceof List) { |
||||||
|
|
||||||
|
List<Object> arguments = (List<Object>) value; |
||||||
|
List<Object> args = new ArrayList<Object>(arguments.size()); |
||||||
|
|
||||||
|
for (Object val : arguments) { |
||||||
|
args.add(unpack(val, context)); |
||||||
|
} |
||||||
|
valueToUse = args; |
||||||
|
} else if (value instanceof java.util.Map) { |
||||||
|
|
||||||
|
Document dbo = new Document(); |
||||||
|
for (java.util.Map.Entry<String, Object> entry : ((java.util.Map<String, Object>) value).entrySet()) { |
||||||
|
dbo.put(entry.getKey(), unpack(entry.getValue(), context)); |
||||||
|
} |
||||||
|
valueToUse = dbo; |
||||||
|
} else { |
||||||
|
valueToUse = unpack(value, context); |
||||||
|
} |
||||||
|
|
||||||
|
return new Document(getMongoMethod(), valueToUse); |
||||||
|
} |
||||||
|
|
||||||
|
protected static List<Field> asFields(String... fieldRefs) { |
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(fieldRefs)) { |
||||||
|
return Collections.emptyList(); |
||||||
|
} |
||||||
|
|
||||||
|
return Fields.fields(fieldRefs).asList(); |
||||||
|
} |
||||||
|
|
||||||
|
private Object unpack(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof AggregationExpression) { |
||||||
|
return ((AggregationExpression) value).toDocument(context); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof Field) { |
||||||
|
return context.getReference((Field) value).toString(); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
|
||||||
|
List<Object> sourceList = (List<Object>) value; |
||||||
|
List<Object> mappedList = new ArrayList<Object>(sourceList.size()); |
||||||
|
|
||||||
|
for (Object item : sourceList) { |
||||||
|
mappedList.add(unpack(item, context)); |
||||||
|
} |
||||||
|
return mappedList; |
||||||
|
} |
||||||
|
|
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
protected List<Object> append(Object value) { |
||||||
|
|
||||||
|
if (this.value instanceof List) { |
||||||
|
|
||||||
|
List<Object> clone = new ArrayList<Object>((List) this.value); |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
for (Object val : (List) value) { |
||||||
|
clone.add(val); |
||||||
|
} |
||||||
|
} else { |
||||||
|
clone.add(value); |
||||||
|
} |
||||||
|
return clone; |
||||||
|
} |
||||||
|
|
||||||
|
return Arrays.asList(this.value, value); |
||||||
|
} |
||||||
|
|
||||||
|
protected java.util.Map<String, Object> append(String key, Object value) { |
||||||
|
|
||||||
|
if (!(this.value instanceof java.util.Map)) { |
||||||
|
throw new IllegalArgumentException("o_O"); |
||||||
|
} |
||||||
|
java.util.Map<String, Object> clone = new LinkedHashMap<String, Object>( |
||||||
|
(java.util.Map<String, Object>) this.value); |
||||||
|
clone.put(key, value); |
||||||
|
return clone; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
protected List<Object> values() { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
return new ArrayList<Object>((List) value); |
||||||
|
} |
||||||
|
if (value instanceof java.util.Map) { |
||||||
|
return new ArrayList<Object>(((java.util.Map) value).values()); |
||||||
|
} |
||||||
|
return new ArrayList<Object>(Arrays.asList(value)); |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract String getMongoMethod(); |
||||||
|
} |
||||||
@ -0,0 +1,641 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.bson.Document; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal accumulator} aggregation operations. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
* @soundtrack Rage Against The Machine - Killing In The Name |
||||||
|
*/ |
||||||
|
public class AccumulatorOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the numeric value referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AccumulatorOperatorFactory valueOf(String fieldReference) { |
||||||
|
return new AccumulatorOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the numeric value referenced resulting from given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AccumulatorOperatorFactory valueOf(AggregationExpression expression) { |
||||||
|
return new AccumulatorOperatorFactory(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class AccumulatorOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AccumulatorOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public AccumulatorOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ArrayOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public AccumulatorOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and calculates and |
||||||
|
* returns the sum. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Sum sum() { |
||||||
|
return usesFieldRef() ? Sum.sumOf(fieldReference) : Sum.sumOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and returns the |
||||||
|
* average value. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Avg avg() { |
||||||
|
return usesFieldRef() ? Avg.avgOf(fieldReference) : Avg.avgOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and returns the |
||||||
|
* maximum value. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Max max() { |
||||||
|
return usesFieldRef() ? Max.maxOf(fieldReference) : Max.maxOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and returns the |
||||||
|
* minimum value. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Min min() { |
||||||
|
return usesFieldRef() ? Min.minOf(fieldReference) : Min.minOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and calculates the |
||||||
|
* population standard deviation of the input values. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevPop stdDevPop() { |
||||||
|
return usesFieldRef() ? StdDevPop.stdDevPopOf(fieldReference) : StdDevPop.stdDevPopOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes the associated numeric value expression and calculates the |
||||||
|
* sample standard deviation of the input values. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevSamp stdDevSamp() { |
||||||
|
return usesFieldRef() ? StdDevSamp.stdDevSampOf(fieldReference) : StdDevSamp.stdDevSampOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return fieldReference != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $sum}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Sum extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Sum(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$sum"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Sum sumOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Sum(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Sum sumOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Sum(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Sum and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Sum(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Sum and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Sum(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $avg}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Avg extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Avg(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$avg"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Avg}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Avg avgOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Avg(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Avg}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Avg avgOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Avg(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Avg} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Avg and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Avg(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Avg} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Avg and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Avg(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $max}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Max extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Max(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$max"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Max}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Max maxOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Max(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Max}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Max maxOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Max(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Max} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Max and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Max(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Max} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Max and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Max(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $min}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Min extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Min(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$min"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Min}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Min minOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Min(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Min}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Min minOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Min(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Min} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Min and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Min(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Min} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Min and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Min(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $stdDevPop}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class StdDevPop extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private StdDevPop(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$stdDevPop"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevPop}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static StdDevPop stdDevPopOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new StdDevPop(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevPop} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static StdDevPop stdDevPopOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new StdDevPop(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevPop} with all previously added arguments appending the given one. <br/> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevPop and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new StdDevPop(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevSamp} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevPop and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new StdDevPop(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $stdDevSamp}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class StdDevSamp extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private StdDevSamp(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$stdDevSamp"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevSamp}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static StdDevSamp stdDevSampOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new StdDevSamp(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevSamp}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static StdDevSamp stdDevSampOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new StdDevSamp(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevSamp} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevSamp and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new StdDevSamp(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link StdDevSamp} with all previously added arguments appending the given one. <br /> |
||||||
|
* <strong>NOTE:</strong> Only possible in {@code $project} stage. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public StdDevSamp and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new StdDevSamp(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.AbstractAggregationExpression#toDocument(java.lang.Object, org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof List) { |
||||||
|
if (((List) value).size() == 1) { |
||||||
|
return super.toDocument(((List<Object>) value).iterator().next(), context); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return super.toDocument(value, context); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,353 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal boolean expressions} that evaluate their argument expressions as booleans and return a boolean |
||||||
|
* as the result. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class BooleanOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the array referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static BooleanOperatorFactory valueOf(String fieldReference) { |
||||||
|
return new BooleanOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the value resulting of the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static BooleanOperatorFactory valueOf(AggregationExpression fieldReference) { |
||||||
|
return new BooleanOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates the boolean value of the referenced field and returns the |
||||||
|
* opposite boolean value. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Not not(String fieldReference) { |
||||||
|
return Not.not(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates the boolean value of {@link AggregationExpression} result |
||||||
|
* and returns the opposite boolean value. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Not not(AggregationExpression expression) { |
||||||
|
return Not.not(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class BooleanOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link BooleanOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public BooleanOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link BooleanOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public BooleanOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates one or more expressions and returns {@literal true} if |
||||||
|
* all of the expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public And and(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return createAnd().andExpression(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates one or more expressions and returns {@literal true} if |
||||||
|
* all of the expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public And and(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return createAnd().andField(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
private And createAnd() { |
||||||
|
return usesFieldRef() ? And.and(Fields.field(fieldReference)) : And.and(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates one or more expressions and returns {@literal true} if |
||||||
|
* any of the expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Or or(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return createOr().orExpression(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates one or more expressions and returns {@literal true} if |
||||||
|
* any of the expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Or or(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return createOr().orField(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
private Or createOr() { |
||||||
|
return usesFieldRef() ? Or.or(Fields.field(fieldReference)) : Or.or(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpression} that evaluates a boolean and returns the opposite boolean value. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Not not() { |
||||||
|
return usesFieldRef() ? Not.not(fieldReference) : Not.not(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return this.fieldReference != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $and}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class And extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private And(List<?> values) { |
||||||
|
super(values); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$and"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link And} that evaluates one or more expressions and returns {@literal true} if all of the |
||||||
|
* expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param expressions |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static And and(Object... expressions) { |
||||||
|
return new And(Arrays.asList(expressions)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link And} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public And andExpression(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new And(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link And} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public And andField(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new And(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link And} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public And andValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new And(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $or}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Or extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Or(List<?> values) { |
||||||
|
super(values); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$or"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Or} that evaluates one or more expressions and returns {@literal true} if any of the |
||||||
|
* expressions are {@literal true}. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Or or(Object... expressions) { |
||||||
|
|
||||||
|
Assert.notNull(expressions, "Expressions must not be null!"); |
||||||
|
return new Or(Arrays.asList(expressions)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Or} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Or orExpression(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Or(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Or} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Or orField(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Or(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Or} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Or orValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Or(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $not}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Not extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Not(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$not"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Not} that evaluates the boolean value of the referenced field and returns the opposite boolean |
||||||
|
* value. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Not not(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Not(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Not} that evaluates the resulting boolean value of the given {@link AggregationExpression} and |
||||||
|
* returns the opposite boolean value. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Not not(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Not(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,879 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal comparison expressions}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class ComparisonOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the field referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ComparisonOperatorFactory valueOf(String fieldReference) { |
||||||
|
return new ComparisonOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the value resulting from the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ComparisonOperatorFactory valueOf(AggregationExpression expression) { |
||||||
|
return new ComparisonOperatorFactory(expression); |
||||||
|
} |
||||||
|
|
||||||
|
public static class ComparisonOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ComparisonOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public ComparisonOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ComparisonOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public ComparisonOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareTo(String fieldReference) { |
||||||
|
return createCmp().compareTo(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareTo(AggregationExpression expression) { |
||||||
|
return createCmp().compareTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareToValue(Object value) { |
||||||
|
return createCmp().compareToValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Cmp createCmp() { |
||||||
|
return usesFieldRef() ? Cmp.valueOf(fieldReference) : Cmp.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is equal to the value of the referenced field. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalTo(String fieldReference) { |
||||||
|
return createEq().equalTo(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is equal to the expression result. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalTo(AggregationExpression expression) { |
||||||
|
return createEq().equalTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is equal to the given value. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalToValue(Object value) { |
||||||
|
return createEq().equalToValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Eq createEq() { |
||||||
|
return usesFieldRef() ? Eq.valueOf(fieldReference) : Eq.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than the value of the referenced field. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThan(String fieldReference) { |
||||||
|
return createGt().greaterThan(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than the expression result. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThan(AggregationExpression expression) { |
||||||
|
return createGt().greaterThan(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than the given value. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThanValue(Object value) { |
||||||
|
return createGt().greaterThanValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Gt createGt() { |
||||||
|
return usesFieldRef() ? Gt.valueOf(fieldReference) : Gt.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than or equivalent to the value of the referenced field. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualTo(String fieldReference) { |
||||||
|
return createGte().greaterThanEqualTo(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than or equivalent to the expression result. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualTo(AggregationExpression expression) { |
||||||
|
return createGte().greaterThanEqualTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is greater than or equivalent to the given value. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualToValue(Object value) { |
||||||
|
return createGte().greaterThanEqualToValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Gte createGte() { |
||||||
|
return usesFieldRef() ? Gte.valueOf(fieldReference) : Gte.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than the value of the referenced field. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThan(String fieldReference) { |
||||||
|
return createLt().lessThan(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than the expression result. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThan(AggregationExpression expression) { |
||||||
|
return createLt().lessThan(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than to the given value. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThanValue(Object value) { |
||||||
|
return createLt().lessThanValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Lt createLt() { |
||||||
|
return usesFieldRef() ? Lt.valueOf(fieldReference) : Lt.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than or equivalent to the value of the referenced field. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualTo(String fieldReference) { |
||||||
|
return createLte().lessThanEqualTo(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than or equivalent to the expression result. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualTo(AggregationExpression expression) { |
||||||
|
return createLte().lessThanEqualTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the first |
||||||
|
* value is less than or equivalent to the given value. |
||||||
|
* |
||||||
|
* @param value |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualToValue(Object value) { |
||||||
|
return createLte().lessThanEqualToValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Lte createLte() { |
||||||
|
return usesFieldRef() ? Lte.valueOf(fieldReference) : Lte.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the values |
||||||
|
* are not equivalent. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualTo(String fieldReference) { |
||||||
|
return createNe().notEqualTo(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the values |
||||||
|
* are not equivalent. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualTo(AggregationExpression expression) { |
||||||
|
return createNe().notEqualTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares two values and returns {@literal true} when the values |
||||||
|
* are not equivalent. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualToValue(Object value) { |
||||||
|
return createNe().notEqualToValue(value); |
||||||
|
} |
||||||
|
|
||||||
|
private Ne createNe() { |
||||||
|
return usesFieldRef() ? Ne.valueOf(fieldReference) : Ne.valueOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return fieldReference != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $cmp}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Cmp extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Cmp(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$cmp"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Cmp}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Cmp valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Cmp(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Cmp}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Cmp valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Cmp(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Cmp} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareTo(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Cmp(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Cmp} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Cmp(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Cmp} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Cmp compareToValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Cmp(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $eq}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Eq extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Eq(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$eq"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Eq valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Eq(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Eq valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Eq(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalTo(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Eq(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Eq(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Eq equalToValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Eq(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $gt}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Gt extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Gt(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$gt"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gt}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Gt valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Gt(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gt}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Gt valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Gt(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThan(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Gt(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThan(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Gt(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gt greaterThanValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Gt(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $lt}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Lt extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Lt(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$lt"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lt}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Lt valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Lt(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lt}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Lt valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Lt(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThan(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Lt(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThan(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Lt(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lt} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lt lessThanValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Lt(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $gte}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Gte extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Gte(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$gte"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gte}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Gte valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Gte(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gte}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Gte valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Gte(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualTo(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Gte(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Gte(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Gte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Gte greaterThanEqualToValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Gte(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $lte}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Lte extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Lte(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$lte"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lte}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Lte valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Lte(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lte}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Lte valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Lte(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualTo(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Lte(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Lte(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Lte} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Lte lessThanEqualToValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Lte(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $ne}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Ne extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Ne(List<?> value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$ne"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Ne}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Ne valueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Ne(asFields(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Ne}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Ne valueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Ne(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Ne} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualTo(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Ne(append(Fields.field(fieldReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Ne} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Ne(append(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Eq} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Ne notEqualToValue(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Ne(append(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,973 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.bson.Document; |
||||||
|
import org.springframework.dao.InvalidDataAccessApiUsageException; |
||||||
|
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.OtherwiseBuilder; |
||||||
|
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Cond.ThenBuilder; |
||||||
|
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Switch.CaseOperator; |
||||||
|
import org.springframework.data.mongodb.core.query.CriteriaDefinition; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
import org.springframework.util.ClassUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal conditional expressions} that evaluate their argument expressions as booleans to a value. |
||||||
|
* |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public class ConditionalOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the field referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ConditionalOperatorFactory when(String fieldReference) { |
||||||
|
return new ConditionalOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the value resulting from the given {@literal expression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ConditionalOperatorFactory when(AggregationExpression expression) { |
||||||
|
return new ConditionalOperatorFactory(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the value resulting from the given {@literal criteriaDefinition}. |
||||||
|
* |
||||||
|
* @param criteriaDefinition must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ConditionalOperatorFactory when(CriteriaDefinition criteriaDefinition) { |
||||||
|
return new ConditionalOperatorFactory(criteriaDefinition); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates an expression and returns the value of the expression if |
||||||
|
* the expression evaluates to a non-null value. If the expression evaluates to a {@literal null} value, including |
||||||
|
* instances of undefined values or missing fields, returns the value of the replacement expression. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IfNull.ThenBuilder ifNull(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return IfNull.ifNull(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates an expression and returns the value of the expression if |
||||||
|
* the expression evaluates to a non-null value. If the expression evaluates to a {@literal null} value, including |
||||||
|
* instances of undefined values or missing fields, returns the value of the replacement expression. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IfNull.ThenBuilder ifNull(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return IfNull.ifNull(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpression} that evaluates a series of {@link CaseOperator} expressions. When it |
||||||
|
* finds an expression which evaluates to {@literal true}, {@code $switch} executes a specified expression and breaks |
||||||
|
* out of the control flow. |
||||||
|
* |
||||||
|
* @param conditions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Switch switchCases(CaseOperator... conditions) { |
||||||
|
return Switch.switchCases(conditions); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpression} that evaluates a series of {@link CaseOperator} expressions. When it |
||||||
|
* finds an expression which evaluates to {@literal true}, {@code $switch} executes a specified expression and breaks |
||||||
|
* out of the control flow. |
||||||
|
* |
||||||
|
* @param conditions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Switch switchCases(List<CaseOperator> conditions) { |
||||||
|
return Switch.switchCases(conditions); |
||||||
|
} |
||||||
|
|
||||||
|
public static class ConditionalOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
private final CriteriaDefinition criteriaDefinition; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ConditionalOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public ConditionalOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
|
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
this.criteriaDefinition = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ConditionalOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public ConditionalOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
|
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
this.criteriaDefinition = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ConditionalOperatorFactory} for given {@link CriteriaDefinition}. |
||||||
|
* |
||||||
|
* @param criteriaDefinition must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public ConditionalOperatorFactory(CriteriaDefinition criteriaDefinition) { |
||||||
|
|
||||||
|
Assert.notNull(criteriaDefinition, "CriteriaDefinition must not be null!"); |
||||||
|
|
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = null; |
||||||
|
this.criteriaDefinition = criteriaDefinition; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpression} that evaluates a boolean expression to return one of the two specified |
||||||
|
* return expressions. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public OtherwiseBuilder then(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return createThenBuilder().then(value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates a boolean expression to return one of the two specified |
||||||
|
* return expressions. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public OtherwiseBuilder thenValueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return createThenBuilder().then(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that evaluates a boolean expression to return one of the two specified |
||||||
|
* return expressions. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public OtherwiseBuilder thenValueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return createThenBuilder().then(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
private ThenBuilder createThenBuilder() { |
||||||
|
|
||||||
|
if (usesFieldRef()) { |
||||||
|
return Cond.newBuilder().when(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
return usesCriteriaDefinition() ? Cond.newBuilder().when(criteriaDefinition) : Cond.newBuilder().when(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return this.fieldReference != null; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesCriteriaDefinition() { |
||||||
|
return this.criteriaDefinition != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Encapsulates the aggregation framework {@code $ifNull} operator. Replacement values can be either {@link Field |
||||||
|
* field references}, {@link AggregationExpression expressions}, values of simple MongoDB types or values that can be |
||||||
|
* converted to a simple MongoDB type. |
||||||
|
* |
||||||
|
* @see http://docs.mongodb.com/manual/reference/operator/aggregation/ifNull/
|
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static class IfNull implements AggregationExpression { |
||||||
|
|
||||||
|
private final Object condition; |
||||||
|
private final Object value; |
||||||
|
|
||||||
|
private IfNull(Object condition, Object value) { |
||||||
|
|
||||||
|
this.condition = condition; |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IfNull}. |
||||||
|
* |
||||||
|
* @param fieldReference the field to check for a {@literal null} value, field reference must not be {@literal null} |
||||||
|
* . |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ThenBuilder ifNull(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new IfNullOperatorBuilder().ifNull(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IfNull}. |
||||||
|
* |
||||||
|
* @param expression the expression to check for a {@literal null} value, field reference must not be |
||||||
|
* {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static ThenBuilder ifNull(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new IfNullOperatorBuilder().ifNull(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(AggregationOperationContext context) { |
||||||
|
|
||||||
|
List<Object> list = new ArrayList<Object>(); |
||||||
|
|
||||||
|
if (condition instanceof Field) { |
||||||
|
list.add(context.getReference((Field) condition).toString()); |
||||||
|
} else if (condition instanceof AggregationExpression) { |
||||||
|
list.add(((AggregationExpression) condition).toDocument(context)); |
||||||
|
} else { |
||||||
|
list.add(condition); |
||||||
|
} |
||||||
|
|
||||||
|
list.add(resolve(value, context)); |
||||||
|
|
||||||
|
return new Document("$ifNull", list); |
||||||
|
} |
||||||
|
|
||||||
|
private Object resolve(Object value, AggregationOperationContext context) { |
||||||
|
|
||||||
|
if (value instanceof Field) { |
||||||
|
return context.getReference((Field) value).toString(); |
||||||
|
} else if (value instanceof AggregationExpression) { |
||||||
|
return ((AggregationExpression) value).toDocument(context); |
||||||
|
} else if (value instanceof Document) { |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
return context.getMappedObject(new Document("$set", value)).get("$set"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static interface IfNullBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param fieldReference the field to check for a {@literal null} value, field reference must not be |
||||||
|
* {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder ifNull(String fieldReference); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param expression the expression to check for a {@literal null} value, field name must not be {@literal null} |
||||||
|
* or empty. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder ifNull(AggregationExpression expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static interface ThenBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param value the value to be used if the {@code $ifNull} condition evaluates {@literal true}. Can be a |
||||||
|
* {@link Document}, a value that is supported by MongoDB or a value that can be converted to a MongoDB |
||||||
|
* representation but must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
IfNull then(Object value); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param fieldReference the field holding the replacement value, must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
IfNull thenValueOf(String fieldReference); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param expression the expression yielding to the replacement value, must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public IfNull thenValueOf(AggregationExpression expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builder for fluent {@link IfNullOperator} creation. |
||||||
|
* |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
static final class IfNullOperatorBuilder implements IfNullBuilder, ThenBuilder { |
||||||
|
|
||||||
|
private Object condition; |
||||||
|
|
||||||
|
private IfNullOperatorBuilder() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new builder for {@link IfNullOperator}. |
||||||
|
* |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static IfNullOperatorBuilder newBuilder() { |
||||||
|
return new IfNullOperatorBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.IfNull.IfNullBuilder#ifNull(java.lang.String) |
||||||
|
*/ |
||||||
|
public ThenBuilder ifNull(String fieldReference) { |
||||||
|
|
||||||
|
Assert.hasText(fieldReference, "FieldReference name must not be null or empty!"); |
||||||
|
this.condition = Fields.field(fieldReference); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.IfNull.IfNullBuilder#ifNull(org.springframework.data.mongodb.core.aggregation.AggregationExpression) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ThenBuilder ifNull(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression name must not be null or empty!"); |
||||||
|
this.condition = expression; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.IfNull.ThenBuilder#then(java.lang.Object) |
||||||
|
*/ |
||||||
|
public IfNull then(Object value) { |
||||||
|
return new IfNull(condition, value); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.IfNull.ThenBuilder#thenValueOf(java.lang.String) |
||||||
|
*/ |
||||||
|
public IfNull thenValueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new IfNull(condition, Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.IfNull.ThenBuilder#thenValueOf(org.springframework.data.mongodb.core.aggregation.AggregationExpression) |
||||||
|
*/ |
||||||
|
public IfNull thenValueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new IfNull(condition, expression); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $switch}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Switch extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Switch(java.util.Map<String, Object> values) { |
||||||
|
super(values); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$switch"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Switch}. |
||||||
|
* |
||||||
|
* @param conditions must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public static Switch switchCases(CaseOperator... conditions) { |
||||||
|
|
||||||
|
Assert.notNull(conditions, "Conditions must not be null!"); |
||||||
|
return switchCases(Arrays.asList(conditions)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Switch}. |
||||||
|
* |
||||||
|
* @param conditions must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public static Switch switchCases(List<CaseOperator> conditions) { |
||||||
|
|
||||||
|
Assert.notNull(conditions, "Conditions must not be null!"); |
||||||
|
return new Switch(Collections.<String, Object> singletonMap("branches", new ArrayList<CaseOperator>(conditions))); |
||||||
|
} |
||||||
|
|
||||||
|
public Switch defaultTo(Object value) { |
||||||
|
return new Switch(append("default", value)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Encapsulates the aggregation framework case document inside a {@code $switch}-operation. |
||||||
|
*/ |
||||||
|
public static class CaseOperator implements AggregationExpression { |
||||||
|
|
||||||
|
private final AggregationExpression when; |
||||||
|
private final Object then; |
||||||
|
|
||||||
|
private CaseOperator(AggregationExpression when, Object then) { |
||||||
|
|
||||||
|
this.when = when; |
||||||
|
this.then = then; |
||||||
|
} |
||||||
|
|
||||||
|
public static ThenBuilder when(final AggregationExpression condition) { |
||||||
|
|
||||||
|
Assert.notNull(condition, "Condition must not be null!"); |
||||||
|
|
||||||
|
return new ThenBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public CaseOperator then(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new CaseOperator(condition, value); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(AggregationOperationContext context) { |
||||||
|
|
||||||
|
Document dbo = new Document("case", when.toDocument(context)); |
||||||
|
|
||||||
|
if (then instanceof AggregationExpression) { |
||||||
|
dbo.put("then", ((AggregationExpression) then).toDocument(context)); |
||||||
|
} else if (then instanceof Field) { |
||||||
|
dbo.put("then", context.getReference((Field) then).toString()); |
||||||
|
} else { |
||||||
|
dbo.put("then", then); |
||||||
|
} |
||||||
|
|
||||||
|
return dbo; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public interface ThenBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the then {@literal value}. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
CaseOperator then(Object value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Encapsulates the aggregation framework {@code $cond} operator. A {@link Cond} allows nested conditions |
||||||
|
* {@code if-then[if-then-else]-else} using {@link Field}, {@link CriteriaDefinition}, {@link AggregationExpression} |
||||||
|
* or a {@link Document custom} condition. Replacement values can be either {@link Field field references}, |
||||||
|
* {@link AggregationExpression expressions}, values of simple MongoDB types or values that can be converted to a |
||||||
|
* simple MongoDB type. |
||||||
|
* |
||||||
|
* @see http://docs.mongodb.com/manual/reference/operator/aggregation/cond/
|
||||||
|
* @author Mark Paluch |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Cond implements AggregationExpression { |
||||||
|
|
||||||
|
private final Object condition; |
||||||
|
private final Object thenValue; |
||||||
|
private final Object otherwiseValue; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link Cond} for a given {@link Field} and {@code then}/{@code otherwise} values. |
||||||
|
* |
||||||
|
* @param condition must not be {@literal null}. |
||||||
|
* @param thenValue must not be {@literal null}. |
||||||
|
* @param otherwiseValue must not be {@literal null}. |
||||||
|
*/ |
||||||
|
private Cond(Field condition, Object thenValue, Object otherwiseValue) { |
||||||
|
this((Object) condition, thenValue, otherwiseValue); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link Cond} for a given {@link CriteriaDefinition} and {@code then}/{@code otherwise} values. |
||||||
|
* |
||||||
|
* @param condition must not be {@literal null}. |
||||||
|
* @param thenValue must not be {@literal null}. |
||||||
|
* @param otherwiseValue must not be {@literal null}. |
||||||
|
*/ |
||||||
|
private Cond(CriteriaDefinition condition, Object thenValue, Object otherwiseValue) { |
||||||
|
this((Object) condition, thenValue, otherwiseValue); |
||||||
|
} |
||||||
|
|
||||||
|
private Cond(Object condition, Object thenValue, Object otherwiseValue) { |
||||||
|
|
||||||
|
Assert.notNull(condition, "Condition must not be null!"); |
||||||
|
Assert.notNull(thenValue, "Then value must not be null!"); |
||||||
|
Assert.notNull(otherwiseValue, "Otherwise value must not be null!"); |
||||||
|
|
||||||
|
assertNotBuilder(condition, "Condition"); |
||||||
|
assertNotBuilder(thenValue, "Then value"); |
||||||
|
assertNotBuilder(otherwiseValue, "Otherwise value"); |
||||||
|
|
||||||
|
this.condition = condition; |
||||||
|
this.thenValue = thenValue; |
||||||
|
this.otherwiseValue = otherwiseValue; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(AggregationOperationContext context) { |
||||||
|
|
||||||
|
Document condObject = new Document(); |
||||||
|
|
||||||
|
condObject.append("if", resolveCriteria(context, condition)); |
||||||
|
condObject.append("then", resolveValue(context, thenValue)); |
||||||
|
condObject.append("else", resolveValue(context, otherwiseValue)); |
||||||
|
|
||||||
|
return new Document("$cond", condObject); |
||||||
|
} |
||||||
|
|
||||||
|
private Object resolveValue(AggregationOperationContext context, Object value) { |
||||||
|
|
||||||
|
if (value instanceof Document || value instanceof Field) { |
||||||
|
return resolve(context, value); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof AggregationExpression) { |
||||||
|
return ((AggregationExpression) value).toDocument(context); |
||||||
|
} |
||||||
|
|
||||||
|
return context.getMappedObject(new Document("$set", value)).get("$set"); |
||||||
|
} |
||||||
|
|
||||||
|
private Object resolveCriteria(AggregationOperationContext context, Object value) { |
||||||
|
|
||||||
|
if (value instanceof Document || value instanceof Field) { |
||||||
|
return resolve(context, value); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof AggregationExpression) { |
||||||
|
return ((AggregationExpression) value).toDocument(context); |
||||||
|
} |
||||||
|
|
||||||
|
if (value instanceof CriteriaDefinition) { |
||||||
|
|
||||||
|
Document mappedObject = context.getMappedObject(((CriteriaDefinition) value).getCriteriaObject()); |
||||||
|
List<Object> clauses = new ArrayList<Object>(); |
||||||
|
|
||||||
|
clauses.addAll(getClauses(context, mappedObject)); |
||||||
|
|
||||||
|
return clauses.size() == 1 ? clauses.get(0) : clauses; |
||||||
|
} |
||||||
|
|
||||||
|
throw new InvalidDataAccessApiUsageException( |
||||||
|
String.format("Invalid value in condition. Supported: Document, Field references, Criteria, got: %s", value)); |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> getClauses(AggregationOperationContext context, Document mappedObject) { |
||||||
|
|
||||||
|
List<Object> clauses = new ArrayList<Object>(); |
||||||
|
|
||||||
|
for (String key : mappedObject.keySet()) { |
||||||
|
|
||||||
|
Object predicate = mappedObject.get(key); |
||||||
|
clauses.addAll(getClauses(context, key, predicate)); |
||||||
|
} |
||||||
|
|
||||||
|
return clauses; |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> getClauses(AggregationOperationContext context, String key, Object predicate) { |
||||||
|
|
||||||
|
List<Object> clauses = new ArrayList<Object>(); |
||||||
|
|
||||||
|
if (predicate instanceof List) { |
||||||
|
|
||||||
|
List<Object> args = new ArrayList<Object>(); |
||||||
|
for (Object clause : (List<?>) predicate) { |
||||||
|
if (clause instanceof Document) { |
||||||
|
args.addAll(getClauses(context, (Document) clause)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
clauses.add(new Document(key, args)); |
||||||
|
|
||||||
|
} else if (predicate instanceof Document) { |
||||||
|
|
||||||
|
Document nested = (Document) predicate; |
||||||
|
|
||||||
|
for (String s : nested.keySet()) { |
||||||
|
|
||||||
|
if (!isKeyword(s)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
List<Object> args = new ArrayList<Object>(); |
||||||
|
args.add("$" + key); |
||||||
|
args.add(nested.get(s)); |
||||||
|
clauses.add(new Document(s, args)); |
||||||
|
} |
||||||
|
|
||||||
|
} else if (!isKeyword(key)) { |
||||||
|
|
||||||
|
List<Object> args = new ArrayList<Object>(); |
||||||
|
args.add("$" + key); |
||||||
|
args.add(predicate); |
||||||
|
clauses.add(new Document("$eq", args)); |
||||||
|
} |
||||||
|
|
||||||
|
return clauses; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Returns whether the given {@link String} is a MongoDB keyword. |
||||||
|
* |
||||||
|
* @param candidate |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private boolean isKeyword(String candidate) { |
||||||
|
return candidate.startsWith("$"); |
||||||
|
} |
||||||
|
|
||||||
|
private Object resolve(AggregationOperationContext context, Object value) { |
||||||
|
|
||||||
|
if (value instanceof Document) { |
||||||
|
return context.getMappedObject((Document) value); |
||||||
|
} |
||||||
|
|
||||||
|
return context.getReference((Field) value).toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private void assertNotBuilder(Object toCheck, String name) { |
||||||
|
Assert.isTrue(!ClassUtils.isAssignableValue(ConditionalExpressionBuilder.class, toCheck), |
||||||
|
String.format("%s must not be of type %s", name, ConditionalExpressionBuilder.class.getSimpleName())); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a builder that allows fluent creation of {@link Cond}. |
||||||
|
* |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static WhenBuilder newBuilder() { |
||||||
|
return ConditionalExpressionBuilder.newBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Cond} by providing the boolean expression used in {@code if}. |
||||||
|
* |
||||||
|
* @param booleanExpression must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static ThenBuilder when(Document booleanExpression) { |
||||||
|
return ConditionalExpressionBuilder.newBuilder().when(booleanExpression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Cond} by providing the {@link AggregationExpression} used in {@code if}. |
||||||
|
* |
||||||
|
* @param expression expression that yields in a boolean result, must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static ThenBuilder when(AggregationExpression expression) { |
||||||
|
return ConditionalExpressionBuilder.newBuilder().when(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Cond} by providing the field reference used in {@code if}. |
||||||
|
* |
||||||
|
* @param booleanField name of a field holding a boolean value, must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static ThenBuilder when(String booleanField) { |
||||||
|
return ConditionalExpressionBuilder.newBuilder().when(booleanField); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Cond} by providing the {@link CriteriaDefinition} used in {@code if}. |
||||||
|
* |
||||||
|
* @param criteria criteria to evaluate, must not be {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
public static ThenBuilder when(CriteriaDefinition criteria) { |
||||||
|
return ConditionalExpressionBuilder.newBuilder().when(criteria); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static interface WhenBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param booleanExpression expression that yields in a boolean result, must not be {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder when(Document booleanExpression); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param expression expression that yields in a boolean result, must not be {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder when(AggregationExpression expression); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param booleanField name of a field holding a boolean value, must not be {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder when(String booleanField); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param criteria criteria to evaluate, must not be {@literal null}. |
||||||
|
* @return the {@link ThenBuilder} |
||||||
|
*/ |
||||||
|
ThenBuilder when(CriteriaDefinition criteria); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static interface ThenBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param value the value to be used if the condition evaluates {@literal true}. Can be a {@link Document}, a |
||||||
|
* value that is supported by MongoDB or a value that can be converted to a MongoDB representation but |
||||||
|
* must not be {@literal null}. |
||||||
|
* @return the {@link OtherwiseBuilder} |
||||||
|
*/ |
||||||
|
OtherwiseBuilder then(Object value); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return the {@link OtherwiseBuilder} |
||||||
|
*/ |
||||||
|
OtherwiseBuilder thenValueOf(String fieldReference); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return the {@link OtherwiseBuilder} |
||||||
|
*/ |
||||||
|
OtherwiseBuilder thenValueOf(AggregationExpression expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
public static interface OtherwiseBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param value the value to be used if the condition evaluates {@literal false}. Can be a {@link Document}, a |
||||||
|
* value that is supported by MongoDB or a value that can be converted to a MongoDB representation but |
||||||
|
* must not be {@literal null}. |
||||||
|
* @return the {@link Cond} |
||||||
|
*/ |
||||||
|
Cond otherwise(Object value); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return the {@link Cond} |
||||||
|
*/ |
||||||
|
Cond otherwiseValueOf(String fieldReference); |
||||||
|
|
||||||
|
/** |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return the {@link Cond} |
||||||
|
*/ |
||||||
|
Cond otherwiseValueOf(AggregationExpression expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Builder for fluent {@link Cond} creation. |
||||||
|
* |
||||||
|
* @author Mark Paluch |
||||||
|
*/ |
||||||
|
static class ConditionalExpressionBuilder implements WhenBuilder, ThenBuilder, OtherwiseBuilder { |
||||||
|
|
||||||
|
private Object condition; |
||||||
|
private Object thenValue; |
||||||
|
|
||||||
|
private ConditionalExpressionBuilder() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new builder for {@link Cond}. |
||||||
|
* |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static ConditionalExpressionBuilder newBuilder() { |
||||||
|
return new ConditionalExpressionBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.WhenBuilder#when(org.bson.Document) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ConditionalExpressionBuilder when(Document booleanExpression) { |
||||||
|
|
||||||
|
Assert.notNull(booleanExpression, "'Boolean expression' must not be null!"); |
||||||
|
|
||||||
|
this.condition = booleanExpression; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.WhenBuilder#when(org.springframework.data.mongodb.core.query.CriteriaDefinition) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ThenBuilder when(CriteriaDefinition criteria) { |
||||||
|
|
||||||
|
Assert.notNull(criteria, "Criteria must not be null!"); |
||||||
|
this.condition = criteria; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.WhenBuilder#when(org.springframework.data.mongodb.core.aggregation.AggregationExpression) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ThenBuilder when(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression field must not be null!"); |
||||||
|
this.condition = expression; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.WhenBuilder#when(java.lang.String) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public ThenBuilder when(String booleanField) { |
||||||
|
|
||||||
|
Assert.hasText(booleanField, "Boolean field name must not be null or empty!"); |
||||||
|
this.condition = Fields.field(booleanField); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.ThenBuilder#then(java.lang.Object) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public OtherwiseBuilder then(Object thenValue) { |
||||||
|
|
||||||
|
Assert.notNull(thenValue, "Then-value must not be null!"); |
||||||
|
this.thenValue = thenValue; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.ThenBuilder#thenValueOf(java.lang.String) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public OtherwiseBuilder thenValueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.thenValue = Fields.field(fieldReference); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.ThenBuilder#thenValueOf(org.springframework.data.mongodb.core.aggregation.AggregationExpression) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public OtherwiseBuilder thenValueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression must not be null!"); |
||||||
|
this.thenValue = expression; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.OtherwiseBuilder#otherwise(java.lang.Object) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Cond otherwise(Object otherwiseValue) { |
||||||
|
|
||||||
|
Assert.notNull(otherwiseValue, "Value must not be null!"); |
||||||
|
return new Cond(condition, thenValue, otherwiseValue); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.OtherwiseBuilder#otherwiseValueOf(java.lang.String) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Cond otherwiseValueOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Cond(condition, thenValue, Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpressions.Cond.OtherwiseBuilder#otherwiseValueOf(org.springframework.data.mongodb.core.aggregation.AggregationExpression) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Cond otherwiseValueOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression must not be null!"); |
||||||
|
return new Cond(condition, thenValue, expression); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal data type} expressions. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
* @soundtrack Clawfinger - Catch Me |
||||||
|
*/ |
||||||
|
public class DataTypeOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Return the BSON data type of the given {@literal field}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Type typeOf(String fieldReference) { |
||||||
|
return Type.typeOf(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $type}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Type extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Type(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$type"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Type}. |
||||||
|
* |
||||||
|
* @param field must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Type typeOf(String field) { |
||||||
|
|
||||||
|
Assert.notNull(field, "Field must not be null!"); |
||||||
|
return new Type(Fields.field(field)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,838 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.LinkedHashMap; |
||||||
|
|
||||||
|
import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.ArithmeticOperatorFactory; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal Date} aggregation operations. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class DateOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the date referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DateOperatorFactory dateOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new DateOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the date resulting from the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DateOperatorFactory dateOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new DateOperatorFactory(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class DateOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ArithmeticOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public DateOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ArithmeticOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public DateOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the day of the year for a date as a number between 1 and |
||||||
|
* 366. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public DayOfYear dayOfYear() { |
||||||
|
return usesFieldRef() ? DayOfYear.dayOfYear(fieldReference) : DayOfYear.dayOfYear(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the day of the month for a date as a number between 1 and |
||||||
|
* 31. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public DayOfMonth dayOfMonth() { |
||||||
|
return usesFieldRef() ? DayOfMonth.dayOfMonth(fieldReference) : DayOfMonth.dayOfMonth(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the day of the week for a date as a number between 1 |
||||||
|
* (Sunday) and 7 (Saturday). |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public DayOfWeek dayOfWeek() { |
||||||
|
return usesFieldRef() ? DayOfWeek.dayOfWeek(fieldReference) : DayOfWeek.dayOfWeek(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the year portion of a date. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Year year() { |
||||||
|
return usesFieldRef() ? Year.yearOf(fieldReference) : Year.yearOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the month of a date as a number between 1 and 12. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Month month() { |
||||||
|
return usesFieldRef() ? Month.monthOf(fieldReference) : Month.monthOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the week of the year for a date as a number between 0 and |
||||||
|
* 53. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Week week() { |
||||||
|
return usesFieldRef() ? Week.weekOf(fieldReference) : Week.weekOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the hour portion of a date as a number between 0 and 23. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Hour hour() { |
||||||
|
return usesFieldRef() ? Hour.hourOf(fieldReference) : Hour.hourOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the minute portion of a date as a number between 0 and |
||||||
|
* 59. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Minute minute() { |
||||||
|
return usesFieldRef() ? Minute.minuteOf(fieldReference) : Minute.minuteOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the second portion of a date as a number between 0 and |
||||||
|
* 59, but can be 60 to account for leap seconds. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Second second() { |
||||||
|
return usesFieldRef() ? Second.secondOf(fieldReference) : Second.secondOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the millisecond portion of a date as an integer between 0 |
||||||
|
* and 999. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Millisecond millisecond() { |
||||||
|
return usesFieldRef() ? Millisecond.millisecondOf(fieldReference) : Millisecond.millisecondOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that converts a date object to a string according to a user-specified |
||||||
|
* {@literal format}. |
||||||
|
* |
||||||
|
* @param format must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public DateToString toString(String format) { |
||||||
|
return (usesFieldRef() ? DateToString.dateOf(fieldReference) : DateToString.dateOf(expression)).toString(format); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the weekday number in ISO 8601 format, ranging from 1 |
||||||
|
* (for Monday) to 7 (for Sunday). |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public IsoDayOfWeek isoDayOfWeek() { |
||||||
|
return usesFieldRef() ? IsoDayOfWeek.isoDayOfWeek(fieldReference) : IsoDayOfWeek.isoDayOfWeek(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the week number in ISO 8601 format, ranging from 1 to 53. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public IsoWeek isoWeek() { |
||||||
|
return usesFieldRef() ? IsoWeek.isoWeekOf(fieldReference) : IsoWeek.isoWeekOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the year number in ISO 8601 format. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public IsoWeekYear isoWeekYear() { |
||||||
|
return usesFieldRef() ? IsoWeekYear.isoWeekYearOf(fieldReference) : IsoWeekYear.isoWeekYearOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return fieldReference != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $dayOfYear}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class DayOfYear extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private DayOfYear(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$dayOfYear"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfYear}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfYear dayOfYear(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new DayOfYear(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfYear}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfYear dayOfYear(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new DayOfYear(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $dayOfMonth}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class DayOfMonth extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private DayOfMonth(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$dayOfMonth"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfMonth}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfMonth dayOfMonth(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new DayOfMonth(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfMonth}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfMonth dayOfMonth(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new DayOfMonth(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $dayOfWeek}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class DayOfWeek extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private DayOfWeek(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$dayOfWeek"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfWeek}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfWeek dayOfWeek(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new DayOfWeek(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DayOfWeek}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static DayOfWeek dayOfWeek(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new DayOfWeek(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $year}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Year extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Year(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$year"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Year}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Year yearOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Year(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Year}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Year yearOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Year(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $month}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Month extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Month(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$month"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Month}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Month monthOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Month(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Month}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Month monthOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Month(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $week}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Week extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Week(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$week"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Week}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Week weekOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Week(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Week}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Week weekOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Week(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $hour}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Hour extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Hour(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$hour"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Hour}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Hour hourOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Hour(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Hour}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Hour hourOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Hour(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $minute}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Minute extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Minute(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$minute"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Minute}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Minute minuteOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Minute(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Minute}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Minute minuteOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Minute(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $second}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Second extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Second(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$second"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Second}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Second secondOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Second(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Second}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Second secondOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Second(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $millisecond}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Millisecond extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Millisecond(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$millisecond"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Millisecond}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Millisecond millisecondOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new Millisecond(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Millisecond}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Millisecond millisecondOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Millisecond(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $dateToString}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class DateToString extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private DateToString(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$dateToString"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link FormatBuilder} allowing to define the date format to apply. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static FormatBuilder dateOf(final String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
|
||||||
|
return new FormatBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public DateToString toString(String format) { |
||||||
|
|
||||||
|
Assert.notNull(format, "Format must not be null!"); |
||||||
|
return new DateToString(argumentMap(Fields.field(fieldReference), format)); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link FormatBuilder} allowing to define the date format to apply. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static FormatBuilder dateOf(final AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
|
||||||
|
return new FormatBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public DateToString toString(String format) { |
||||||
|
|
||||||
|
Assert.notNull(format, "Format must not be null!"); |
||||||
|
return new DateToString(argumentMap(expression, format)); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private static java.util.Map<String, Object> argumentMap(Object date, String format) { |
||||||
|
|
||||||
|
java.util.Map<String, Object> args = new LinkedHashMap<String, Object>(2); |
||||||
|
args.put("format", format); |
||||||
|
args.put("date", date); |
||||||
|
return args; |
||||||
|
} |
||||||
|
|
||||||
|
public interface FormatBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link DateToString} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param format must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
DateToString toString(String format); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $isoDayOfWeek}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class IsoDayOfWeek extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private IsoDayOfWeek(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$isoDayOfWeek"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IsoDayOfWeek}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoDayOfWeek isoDayOfWeek(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new IsoDayOfWeek(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IsoDayOfWeek}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoDayOfWeek isoDayOfWeek(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new IsoDayOfWeek(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $isoWeek}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class IsoWeek extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private IsoWeek(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$isoWeek"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IsoWeek}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoWeek isoWeekOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new IsoWeek(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IsoWeek}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoWeek isoWeekOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new IsoWeek(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $isoWeekYear}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class IsoWeekYear extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private IsoWeekYear(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$isoWeekYear"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link IsoWeekYear}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoWeekYear isoWeekYearOf(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
return new IsoWeekYear(Fields.field(fieldReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Millisecond}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static IsoWeekYear isoWeekYearOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new IsoWeekYear(expression); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal literal} aggregation operations. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class LiteralOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the value referenced by given {@literal value}. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static LiteralOperatorFactory valueOf(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new LiteralOperatorFactory(value); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class LiteralOperatorFactory { |
||||||
|
|
||||||
|
private final Object value; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link LiteralOperatorFactory} for given {@literal value}. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public LiteralOperatorFactory(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
this.value = value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that returns the associated value without parsing. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public Literal asLiteral() { |
||||||
|
return Literal.asLiteral(value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $literal}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class Literal extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private Literal(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$literal"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Literal}. |
||||||
|
* |
||||||
|
* @param value must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Literal asLiteral(Object value) { |
||||||
|
|
||||||
|
Assert.notNull(value, "Value must not be null!"); |
||||||
|
return new Literal(value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,666 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal Set expressions} which perform {@literal set} operation on arrays, treating arrays as sets. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class SetOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the array referenced by given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetOperatorFactory arrayAsSet(String fieldReference) { |
||||||
|
return new SetOperatorFactory(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Take the array resulting from the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetOperatorFactory arrayAsSet(AggregationExpression expression) { |
||||||
|
return new SetOperatorFactory(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetOperatorFactory { |
||||||
|
|
||||||
|
private final String fieldReference; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetOperatorFactory} for given {@literal fieldReference}. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public SetOperatorFactory(String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
this.fieldReference = fieldReference; |
||||||
|
this.expression = null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetOperatorFactory} for given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
*/ |
||||||
|
public SetOperatorFactory(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
this.fieldReference = null; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares the previously mentioned field to one or more arrays and |
||||||
|
* returns {@literal true} if they have the same distinct elements and {@literal false} otherwise. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetEquals isEqualTo(String... arrayReferences) { |
||||||
|
return createSetEquals().isEqualTo(arrayReferences); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that compares the previously mentioned field to one or more arrays and |
||||||
|
* returns {@literal true} if they have the same distinct elements and {@literal false} otherwise. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetEquals isEqualTo(AggregationExpression... expressions) { |
||||||
|
return createSetEquals().isEqualTo(expressions); |
||||||
|
} |
||||||
|
|
||||||
|
private SetEquals createSetEquals() { |
||||||
|
return usesFieldRef() ? SetEquals.arrayAsSet(fieldReference) : SetEquals.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and one or more |
||||||
|
* arrays and returns an array that contains the elements that appear in every of those. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIntersection intersects(String... arrayReferences) { |
||||||
|
return createSetIntersection().intersects(arrayReferences); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and one or more |
||||||
|
* arrays and returns an array that contains the elements that appear in every of those. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIntersection intersects(AggregationExpression... expressions) { |
||||||
|
return createSetIntersection().intersects(expressions); |
||||||
|
} |
||||||
|
|
||||||
|
private SetIntersection createSetIntersection() { |
||||||
|
return usesFieldRef() ? SetIntersection.arrayAsSet(fieldReference) : SetIntersection.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and one or more |
||||||
|
* arrays and returns an array that contains the elements that appear in any of those. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetUnion union(String... arrayReferences) { |
||||||
|
return createSetUnion().union(arrayReferences); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and one or more |
||||||
|
* arrays and returns an array that contains the elements that appear in any of those. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetUnion union(AggregationExpression... expressions) { |
||||||
|
return createSetUnion().union(expressions); |
||||||
|
} |
||||||
|
|
||||||
|
private SetUnion createSetUnion() { |
||||||
|
return usesFieldRef() ? SetUnion.arrayAsSet(fieldReference) : SetUnion.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and returns an |
||||||
|
* array containing the elements that do not exist in the given {@literal arrayReference}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetDifference differenceTo(String arrayReference) { |
||||||
|
return createSetDifference().differenceTo(arrayReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and returns an |
||||||
|
* array containing the elements that do not exist in the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetDifference differenceTo(AggregationExpression expression) { |
||||||
|
return createSetDifference().differenceTo(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private SetDifference createSetDifference() { |
||||||
|
return usesFieldRef() ? SetDifference.arrayAsSet(fieldReference) : SetDifference.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and returns |
||||||
|
* {@literal true} if it is a subset of the given {@literal arrayReference}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIsSubset isSubsetOf(String arrayReference) { |
||||||
|
return createSetIsSubset().isSubsetOf(arrayReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and returns |
||||||
|
* {@literal true} if it is a subset of the given {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIsSubset isSubsetOf(AggregationExpression expression) { |
||||||
|
return createSetIsSubset().isSubsetOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private SetIsSubset createSetIsSubset() { |
||||||
|
return usesFieldRef() ? SetIsSubset.arrayAsSet(fieldReference) : SetIsSubset.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that takes array of the previously mentioned field and returns |
||||||
|
* {@literal true} if any of the elements are {@literal true} and {@literal false} otherwise. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public AnyElementTrue anyElementTrue() { |
||||||
|
return usesFieldRef() ? AnyElementTrue.arrayAsSet(fieldReference) : AnyElementTrue.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AggregationExpressions} that tkes array of the previously mentioned field and returns |
||||||
|
* {@literal true} if no elements is {@literal false}. |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public AllElementsTrue allElementsTrue() { |
||||||
|
return usesFieldRef() ? AllElementsTrue.arrayAsSet(fieldReference) : AllElementsTrue.arrayAsSet(expression); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean usesFieldRef() { |
||||||
|
return this.fieldReference != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $setEquals}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetEquals extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private SetEquals(List<?> arrays) { |
||||||
|
super(arrays); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$setEquals"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create new {@link SetEquals}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetEquals arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetEquals(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create new {@link SetEquals}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetEquals arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetEquals(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link java.util.Set} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetEquals isEqualTo(String... arrayReferences) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReferences, "ArrayReferences must not be null!"); |
||||||
|
return new SetEquals(append(Fields.fields(arrayReferences).asList())); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetEquals isEqualTo(AggregationExpression... expressions) { |
||||||
|
|
||||||
|
Assert.notNull(expressions, "Expressions must not be null!"); |
||||||
|
return new SetEquals(append(Arrays.asList(expressions))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Sum} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param array must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetEquals isEqualTo(Object[] array) { |
||||||
|
|
||||||
|
Assert.notNull(array, "Array must not be null!"); |
||||||
|
return new SetEquals(append(array)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $setIntersection}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetIntersection extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private SetIntersection(List<?> arrays) { |
||||||
|
super(arrays); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$setIntersection"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIntersection} |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetIntersection arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetIntersection(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIntersection}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetIntersection arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetIntersection(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIntersection} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIntersection intersects(String... arrayReferences) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReferences, "ArrayReferences must not be null!"); |
||||||
|
return new SetIntersection(append(asFields(arrayReferences))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIntersection} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIntersection intersects(AggregationExpression... expressions) { |
||||||
|
|
||||||
|
Assert.notNull(expressions, "Expressions must not be null!"); |
||||||
|
return new SetIntersection(append(Arrays.asList(expressions))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $setUnion}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetUnion extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private SetUnion(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$setUnion"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetUnion}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetUnion arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetUnion(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetUnion}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetUnion arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetUnion(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetUnion} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param arrayReferences must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetUnion union(String... arrayReferences) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReferences, "ArrayReferences must not be null!"); |
||||||
|
return new SetUnion(append(asFields(arrayReferences))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetUnion} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expressions must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetUnion union(AggregationExpression... expressions) { |
||||||
|
|
||||||
|
Assert.notNull(expressions, "Expressions must not be null!"); |
||||||
|
return new SetUnion(append(Arrays.asList(expressions))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $setDifference}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetDifference extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private SetDifference(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$setDifference"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetDifference}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetDifference arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetDifference(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetDifference}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetDifference arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetDifference(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetDifference} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetDifference differenceTo(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetDifference(append(Fields.field(arrayReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetDifference} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetDifference differenceTo(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetDifference(append(expression)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $setIsSubset}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class SetIsSubset extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private SetIsSubset(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$setIsSubset"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIsSubset}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetIsSubset arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetIsSubset(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIsSubset}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static SetIsSubset arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetIsSubset(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIsSubset} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIsSubset isSubsetOf(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new SetIsSubset(append(Fields.field(arrayReference))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link SetIsSubset} with all previously added arguments appending the given one. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public SetIsSubset isSubsetOf(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new SetIsSubset(append(expression)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $anyElementTrue}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class AnyElementTrue extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private AnyElementTrue(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$anyElementTrue"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AnyElementTrue}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AnyElementTrue arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new AnyElementTrue(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AnyElementTrue}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AnyElementTrue arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new AnyElementTrue(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
public AnyElementTrue anyElementTrue() { |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $allElementsTrue}. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class AllElementsTrue extends AbstractAggregationExpression { |
||||||
|
|
||||||
|
private AllElementsTrue(Object value) { |
||||||
|
super(value); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String getMongoMethod() { |
||||||
|
return "$allElementsTrue"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AllElementsTrue}. |
||||||
|
* |
||||||
|
* @param arrayReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AllElementsTrue arrayAsSet(String arrayReference) { |
||||||
|
|
||||||
|
Assert.notNull(arrayReference, "ArrayReference must not be null!"); |
||||||
|
return new AllElementsTrue(asFields(arrayReference)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link AllElementsTrue}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AllElementsTrue arrayAsSet(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new AllElementsTrue(Collections.singletonList(expression)); |
||||||
|
} |
||||||
|
|
||||||
|
public AllElementsTrue allElementsTrue() { |
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,389 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2016. the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.aggregation; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.bson.Document; |
||||||
|
import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Gateway to {@literal variable} aggregation operations. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @author Mark Paluch |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public class VariableOperators { |
||||||
|
|
||||||
|
/** |
||||||
|
* Starts building new {@link Map} that applies an {@link AggregationExpression} to each item of a referenced array |
||||||
|
* and returns an array with the applied results. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Map.AsBuilder mapItemsOf(String fieldReference) { |
||||||
|
return Map.itemsOf(fieldReference); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Starts building new {@link Map} that applies an {@link AggregationExpression} to each item of a referenced array |
||||||
|
* and returns an array with the applied results. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Map.AsBuilder mapItemsOf(AggregationExpression expression) { |
||||||
|
return Map.itemsOf(expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Let} that allows definition of {@link ExpressionVariable} that can be used within a |
||||||
|
* nested {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param variables must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Let.LetBuilder define(ExpressionVariable... variables) { |
||||||
|
return Let.define(variables); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Let} that allows definition of {@link ExpressionVariable} that can be used within a |
||||||
|
* nested {@link AggregationExpression}. |
||||||
|
* |
||||||
|
* @param variables must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Let.LetBuilder define(Collection<ExpressionVariable> variables) { |
||||||
|
return Let.define(variables); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $map}. |
||||||
|
*/ |
||||||
|
public static class Map implements AggregationExpression { |
||||||
|
|
||||||
|
private Object sourceArray; |
||||||
|
private String itemVariableName; |
||||||
|
private AggregationExpression functionToApply; |
||||||
|
|
||||||
|
private Map(Object sourceArray, String itemVariableName, AggregationExpression functionToApply) { |
||||||
|
|
||||||
|
Assert.notNull(sourceArray, "SourceArray must not be null!"); |
||||||
|
Assert.notNull(itemVariableName, "ItemVariableName must not be null!"); |
||||||
|
Assert.notNull(functionToApply, "FunctionToApply must not be null!"); |
||||||
|
|
||||||
|
this.sourceArray = sourceArray; |
||||||
|
this.itemVariableName = itemVariableName; |
||||||
|
this.functionToApply = functionToApply; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Starts building new {@link Map} that applies an {@link AggregationExpression} to each item of a referenced array |
||||||
|
* and returns an array with the applied results. |
||||||
|
* |
||||||
|
* @param fieldReference must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AsBuilder itemsOf(final String fieldReference) { |
||||||
|
|
||||||
|
Assert.notNull(fieldReference, "FieldReference must not be null!"); |
||||||
|
|
||||||
|
return new AsBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public FunctionBuilder as(final String variableName) { |
||||||
|
|
||||||
|
Assert.notNull(variableName, "VariableName must not be null!"); |
||||||
|
|
||||||
|
return new FunctionBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map andApply(final AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression must not be null!"); |
||||||
|
return new Map(Fields.field(fieldReference), variableName, expression); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
/** |
||||||
|
* Starts building new {@link Map} that applies an {@link AggregationExpression} to each item of a referenced array |
||||||
|
* and returns an array with the applied results. |
||||||
|
* |
||||||
|
* @param source must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static AsBuilder itemsOf(final AggregationExpression source) { |
||||||
|
|
||||||
|
Assert.notNull(source, "AggregationExpression must not be null!"); |
||||||
|
|
||||||
|
return new AsBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public FunctionBuilder as(final String variableName) { |
||||||
|
|
||||||
|
Assert.notNull(variableName, "VariableName must not be null!"); |
||||||
|
|
||||||
|
return new FunctionBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Map andApply(final AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "AggregationExpression must not be null!"); |
||||||
|
return new Map(source, variableName, expression); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(final AggregationOperationContext context) { |
||||||
|
return toMap(ExposedFields.synthetic(Fields.fields(itemVariableName)), context); |
||||||
|
} |
||||||
|
|
||||||
|
private Document toMap(ExposedFields exposedFields, AggregationOperationContext context) { |
||||||
|
|
||||||
|
Document map = new Document(); |
||||||
|
InheritingExposedFieldsAggregationOperationContext operationContext = new InheritingExposedFieldsAggregationOperationContext( |
||||||
|
exposedFields, context); |
||||||
|
|
||||||
|
Document input; |
||||||
|
if (sourceArray instanceof Field) { |
||||||
|
input = new Document("input", context.getReference((Field) sourceArray).toString()); |
||||||
|
} else { |
||||||
|
input = new Document("input", ((AggregationExpression) sourceArray).toDocument(context)); |
||||||
|
} |
||||||
|
|
||||||
|
map.putAll(context.getMappedObject(input)); |
||||||
|
map.put("as", itemVariableName); |
||||||
|
map.put("in", |
||||||
|
functionToApply.toDocument(new NestedDelegatingExpressionAggregationOperationContext(operationContext))); |
||||||
|
|
||||||
|
return new Document("$map", map); |
||||||
|
} |
||||||
|
|
||||||
|
public interface AsBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* Define the {@literal variableName} for addressing items within the array. |
||||||
|
* |
||||||
|
* @param variableName must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
FunctionBuilder as(String variableName); |
||||||
|
} |
||||||
|
|
||||||
|
public interface FunctionBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link Map} that applies the given {@link AggregationExpression} to each item of the referenced |
||||||
|
* array and returns an array with the applied results. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
Map andApply(AggregationExpression expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@link AggregationExpression} for {@code $let} that binds {@link AggregationExpression} to variables for use in the |
||||||
|
* specified {@code in} expression, and returns the result of the expression. |
||||||
|
* |
||||||
|
* @author Christoph Strobl |
||||||
|
* @since 1.10 |
||||||
|
*/ |
||||||
|
public static class Let implements AggregationExpression { |
||||||
|
|
||||||
|
private final List<ExpressionVariable> vars; |
||||||
|
private final AggregationExpression expression; |
||||||
|
|
||||||
|
private Let(List<ExpressionVariable> vars, AggregationExpression expression) { |
||||||
|
|
||||||
|
this.vars = vars; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Let} by defining the variables for {@code $vars}. |
||||||
|
* |
||||||
|
* @param variables must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static LetBuilder define(final Collection<ExpressionVariable> variables) { |
||||||
|
|
||||||
|
Assert.notNull(variables, "Variables must not be null!"); |
||||||
|
|
||||||
|
return new LetBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Let andApply(final AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Let(new ArrayList<ExpressionVariable>(variables), expression); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Start creating new {@link Let} by defining the variables for {@code $vars}. |
||||||
|
* |
||||||
|
* @param variables must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static LetBuilder define(final ExpressionVariable... variables) { |
||||||
|
|
||||||
|
Assert.notNull(variables, "Variables must not be null!"); |
||||||
|
|
||||||
|
return new LetBuilder() { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Let andApply(final AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new Let(Arrays.asList(variables), expression); |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
public interface LetBuilder { |
||||||
|
|
||||||
|
/** |
||||||
|
* Define the {@link AggregationExpression} to evaluate. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
Let andApply(AggregationExpression expression); |
||||||
|
} |
||||||
|
|
||||||
|
/* (non-Javadoc) |
||||||
|
* @see org.springframework.data.mongodb.core.aggregation.AggregationExpression#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public Document toDocument(final AggregationOperationContext context) { |
||||||
|
return toLet(ExposedFields.synthetic(Fields.fields(getVariableNames())), context); |
||||||
|
} |
||||||
|
|
||||||
|
private String[] getVariableNames() { |
||||||
|
|
||||||
|
String[] varNames = new String[this.vars.size()]; |
||||||
|
for (int i = 0; i < this.vars.size(); i++) { |
||||||
|
varNames[i] = this.vars.get(i).variableName; |
||||||
|
} |
||||||
|
|
||||||
|
return varNames; |
||||||
|
} |
||||||
|
|
||||||
|
private Document toLet(ExposedFields exposedFields, AggregationOperationContext context) { |
||||||
|
|
||||||
|
Document letExpression = new Document(); |
||||||
|
Document mappedVars = new Document(); |
||||||
|
InheritingExposedFieldsAggregationOperationContext operationContext = new InheritingExposedFieldsAggregationOperationContext( |
||||||
|
exposedFields, context); |
||||||
|
|
||||||
|
for (ExpressionVariable var : this.vars) { |
||||||
|
mappedVars.putAll(getMappedVariable(var, context)); |
||||||
|
} |
||||||
|
|
||||||
|
letExpression.put("vars", mappedVars); |
||||||
|
letExpression.put("in", getMappedIn(operationContext)); |
||||||
|
|
||||||
|
return new Document("$let", letExpression); |
||||||
|
} |
||||||
|
|
||||||
|
private Document getMappedVariable(ExpressionVariable var, AggregationOperationContext context) { |
||||||
|
|
||||||
|
return new Document(var.variableName, var.expression instanceof AggregationExpression |
||||||
|
? ((AggregationExpression) var.expression).toDocument(context) : var.expression); |
||||||
|
} |
||||||
|
|
||||||
|
private Object getMappedIn(AggregationOperationContext context) { |
||||||
|
return expression.toDocument(new NestedDelegatingExpressionAggregationOperationContext(context)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Christoph Strobl |
||||||
|
*/ |
||||||
|
public static class ExpressionVariable { |
||||||
|
|
||||||
|
private final String variableName; |
||||||
|
private final Object expression; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates new {@link ExpressionVariable}. |
||||||
|
* |
||||||
|
* @param variableName can be {@literal null}. |
||||||
|
* @param expression can be {@literal null}. |
||||||
|
*/ |
||||||
|
private ExpressionVariable(String variableName, Object expression) { |
||||||
|
|
||||||
|
this.variableName = variableName; |
||||||
|
this.expression = expression; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new {@link ExpressionVariable} with given name. |
||||||
|
* |
||||||
|
* @param variableName must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public static ExpressionVariable newVariable(String variableName) { |
||||||
|
|
||||||
|
Assert.notNull(variableName, "VariableName must not be null!"); |
||||||
|
return new ExpressionVariable(variableName, null); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new {@link ExpressionVariable} with current name and given {@literal expression}. |
||||||
|
* |
||||||
|
* @param expression must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public ExpressionVariable forExpression(AggregationExpression expression) { |
||||||
|
|
||||||
|
Assert.notNull(expression, "Expression must not be null!"); |
||||||
|
return new ExpressionVariable(variableName, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create a new {@link ExpressionVariable} with current name and given {@literal expressionObject}. |
||||||
|
* |
||||||
|
* @param expressionObject must not be {@literal null}. |
||||||
|
* @return never {@literal null}. |
||||||
|
*/ |
||||||
|
public ExpressionVariable forExpression(Document expressionObject) { |
||||||
|
|
||||||
|
Assert.notNull(expressionObject, "Expression must not be null!"); |
||||||
|
return new ExpressionVariable(variableName, expressionObject); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue