DATAMONGO-2287 - Polishing.
Add new factory method for ArrayOperators that deals with a collection of values. Original pull request: #760.
This commit is contained in:
committed by
Mark Paluch
parent
a3ef9b5856
commit
8b406b23ff
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -58,13 +59,25 @@ public class ArrayOperators {
|
||||
return new ArrayOperatorFactory(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the given {@link Collection values} {@link AggregationExpression}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link ArrayOperatorFactory}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ArrayOperatorFactory arrayOf(Collection<?> values) {
|
||||
return new ArrayOperatorFactory(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public static class ArrayOperatorFactory {
|
||||
|
||||
private final String fieldReference;
|
||||
private final AggregationExpression expression;
|
||||
private final @Nullable String fieldReference;
|
||||
private final @Nullable AggregationExpression expression;
|
||||
private final @Nullable Collection values;
|
||||
|
||||
/**
|
||||
* Creates new {@link ArrayOperatorFactory} for given {@literal fieldReference}.
|
||||
@@ -76,6 +89,7 @@ public class ArrayOperators {
|
||||
Assert.notNull(fieldReference, "FieldReference must not be null!");
|
||||
this.fieldReference = fieldReference;
|
||||
this.expression = null;
|
||||
this.values = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +102,21 @@ public class ArrayOperators {
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
this.fieldReference = null;
|
||||
this.expression = expression;
|
||||
this.values = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link ArrayOperatorFactory} for given values.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public ArrayOperatorFactory(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
this.fieldReference = null;
|
||||
this.expression = null;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +157,12 @@ public class ArrayOperators {
|
||||
}
|
||||
|
||||
private ArrayElemAt createArrayElemAt() {
|
||||
return usesFieldRef() ? ArrayElemAt.arrayOf(fieldReference) : ArrayElemAt.arrayOf(expression);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return ArrayElemAt.arrayOf(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? ArrayElemAt.arrayOf(expression) : ArrayElemAt.arrayOf(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,7 +192,12 @@ public class ArrayOperators {
|
||||
}
|
||||
|
||||
private ConcatArrays createConcatArrays() {
|
||||
return usesFieldRef() ? ConcatArrays.arrayOf(fieldReference) : ConcatArrays.arrayOf(expression);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return ConcatArrays.arrayOf(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? ConcatArrays.arrayOf(expression) : ConcatArrays.arrayOf(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +207,13 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public AsBuilder filter() {
|
||||
return Filter.filter(fieldReference);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return Filter.filter(fieldReference);
|
||||
}
|
||||
|
||||
Assert.state(values != null, "Values must not be null!");
|
||||
return Filter.filter(new ArrayList<>(values));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,6 +222,9 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public IsArray isArray() {
|
||||
|
||||
Assert.state(values == null, "Does it make sense to call isArray on an array? Maybe just skip it?");
|
||||
|
||||
return usesFieldRef() ? IsArray.isArray(fieldReference) : IsArray.isArray(expression);
|
||||
}
|
||||
|
||||
@@ -186,7 +234,12 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public Size length() {
|
||||
return usesFieldRef() ? Size.lengthOfArray(fieldReference) : Size.lengthOfArray(expression);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return Size.lengthOfArray(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? Size.lengthOfArray(expression) : Size.lengthOfArray(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -195,7 +248,12 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public Slice slice() {
|
||||
return usesFieldRef() ? Slice.sliceArrayOf(fieldReference) : Slice.sliceArrayOf(expression);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return Slice.sliceArrayOf(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? Slice.sliceArrayOf(expression) : Slice.sliceArrayOf(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,8 +264,13 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public IndexOfArray indexOf(Object value) {
|
||||
return usesFieldRef() ? IndexOfArray.arrayOf(fieldReference).indexOf(value)
|
||||
: IndexOfArray.arrayOf(expression).indexOf(value);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return IndexOfArray.arrayOf(fieldReference).indexOf(value);
|
||||
}
|
||||
|
||||
return usesExpression() ? IndexOfArray.arrayOf(expression).indexOf(value)
|
||||
: IndexOfArray.arrayOf(values).indexOf(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,7 +279,13 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public ReverseArray reverse() {
|
||||
return usesFieldRef() ? ReverseArray.reverseArrayOf(fieldReference) : ReverseArray.reverseArrayOf(expression);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return ReverseArray.reverseArrayOf(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? ReverseArray.reverseArrayOf(expression)
|
||||
: ReverseArray.reverseArrayOf(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +323,12 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public Zip zipWith(Object... arrays) {
|
||||
return (usesFieldRef() ? Zip.arrayOf(fieldReference) : Zip.arrayOf(expression)).zip(arrays);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return Zip.arrayOf(fieldReference).zip(arrays);
|
||||
}
|
||||
|
||||
return (usesExpression() ? Zip.arrayOf(expression) : Zip.arrayOf(values)).zip(arrays);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +339,12 @@ public class ArrayOperators {
|
||||
* @return
|
||||
*/
|
||||
public In containsValue(Object value) {
|
||||
return (usesFieldRef() ? In.arrayOf(fieldReference) : In.arrayOf(expression)).containsValue(value);
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return In.arrayOf(fieldReference).containsValue(value);
|
||||
}
|
||||
|
||||
return (usesExpression() ? In.arrayOf(expression) : In.arrayOf(values)).containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,8 +356,11 @@ public class ArrayOperators {
|
||||
*/
|
||||
public ArrayToObject toObject() {
|
||||
|
||||
return usesFieldRef() ? ArrayToObject.arrayValueOfToObject(fieldReference)
|
||||
: ArrayToObject.arrayValueOfToObject(expression);
|
||||
if (usesFieldRef()) {
|
||||
return ArrayToObject.arrayValueOfToObject(fieldReference);
|
||||
}
|
||||
|
||||
return usesExpression() ? ArrayToObject.arrayValueOfToObject(expression) : ArrayToObject.arrayToObject(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,9 +377,20 @@ public class ArrayOperators {
|
||||
Reduce startingWith(Object initialValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@link #fieldReference} is not {@literal null}.
|
||||
*/
|
||||
private boolean usesFieldRef() {
|
||||
return fieldReference != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@link #expression} is not {@literal null}.
|
||||
* @since 2.2
|
||||
*/
|
||||
private boolean usesExpression() {
|
||||
return expression != null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,6 +433,19 @@ public class ArrayOperators {
|
||||
return new ArrayElemAt(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link ArrayElemAt}.
|
||||
*
|
||||
* @param values The array members. Must not be {@literal null}.
|
||||
* @return new instance of {@link ArrayElemAt}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ArrayElemAt arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
return new ArrayElemAt(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
public ArrayElemAt elementAt(int index) {
|
||||
return new ArrayElemAt(append(index));
|
||||
}
|
||||
@@ -397,6 +503,19 @@ public class ArrayOperators {
|
||||
return new ConcatArrays(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link ConcatArrays}.
|
||||
*
|
||||
* @param values The array members. Must not be {@literal null}.
|
||||
* @return new instance of {@link ConcatArrays}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ConcatArrays arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
return new ConcatArrays(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
public ConcatArrays concat(String arrayFieldReference) {
|
||||
|
||||
Assert.notNull(arrayFieldReference, "ArrayFieldReference must not be null!");
|
||||
@@ -741,6 +860,19 @@ public class ArrayOperators {
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
return new Size(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link Size}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link Size}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static Size lengthOfArray(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
return new Size(Collections.singletonList(values));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -783,6 +915,19 @@ public class ArrayOperators {
|
||||
return new Slice(Collections.singletonList(expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link Slice}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link Slice}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static Slice sliceArrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
return new Slice(Collections.singletonList(values));
|
||||
}
|
||||
|
||||
public Slice itemCount(int nrElements) {
|
||||
return new Slice(append(nrElements));
|
||||
}
|
||||
@@ -853,6 +998,19 @@ public class ArrayOperators {
|
||||
return new IndexOfArrayBuilder(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start creating new {@link IndexOfArray}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link IndexOfArray}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static IndexOfArrayBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
return new IndexOfArrayBuilder(values);
|
||||
}
|
||||
|
||||
public IndexOfArray within(Range<Long> range) {
|
||||
return new IndexOfArray(append(AggregationUtils.toRangeValues(range)));
|
||||
}
|
||||
@@ -1007,6 +1165,17 @@ public class ArrayOperators {
|
||||
public static ReverseArray reverseArrayOf(AggregationExpression expression) {
|
||||
return new ReverseArray(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link ReverseArray}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link ReverseArray}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ReverseArray reverseArrayOf(Collection<?> values) {
|
||||
return new ReverseArray(values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1359,6 +1528,19 @@ public class ArrayOperators {
|
||||
return new ZipBuilder(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start creating new {@link Zip}.
|
||||
*
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link Zip}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ZipBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(values, "Expression must not be null!");
|
||||
return new ZipBuilder(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new {@link Zip} and set the {@code useLongestLength} property to {@literal true}.
|
||||
*
|
||||
@@ -1483,7 +1665,7 @@ public class ArrayOperators {
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static InBuilder arrayOf(final AggregationExpression expression) {
|
||||
public static InBuilder arrayOf(AggregationExpression expression) {
|
||||
|
||||
Assert.notNull(expression, "Expression must not be null!");
|
||||
|
||||
@@ -1501,13 +1683,13 @@ public class ArrayOperators {
|
||||
/**
|
||||
* Support for Aggregation In Search an Element in List of Objects to Filter Start creating {@link In}.
|
||||
*
|
||||
* @author Shashank Sharma
|
||||
* @param elementList must not be {@literal null}.
|
||||
* @return
|
||||
* @param values must not be {@literal null}.
|
||||
* @return new instance of {@link InBuilder}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public static InBuilder arrayOf(final List<Object> elementList) {
|
||||
public static InBuilder arrayOf(Collection<?> values) {
|
||||
|
||||
Assert.notNull(elementList, "Elements must not be null!");
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
|
||||
return new InBuilder() {
|
||||
|
||||
@@ -1515,7 +1697,7 @@ public class ArrayOperators {
|
||||
public In containsValue(Object value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
return new In(Arrays.asList(value, elementList));
|
||||
return new In(Arrays.asList(value, values));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayToO
|
||||
*/
|
||||
public class ArrayOperatorsUnitTests {
|
||||
|
||||
static final List<Object> VALUE_LIST = Arrays.asList(1, "2", new Document("_id", 3));
|
||||
static final String VALUE_LIST_STRING = "[1, \"2\", { \"_id\" : 3 }]";
|
||||
static final String EXPRESSION_STRING = "{ \"$stablemaster\" : \"burrich\" }";
|
||||
static final Document EXPRESSION_DOC = Document.parse(EXPRESSION_STRING);
|
||||
static final AggregationExpression EXPRESSION = context -> EXPRESSION_DOC;
|
||||
@@ -64,10 +66,67 @@ public class ArrayOperatorsUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void inArrayAggregationWithArgumentList() {
|
||||
public void arrayElementAtWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.In.arrayOf(Arrays.asList("Shashank", "Sharma")).containsValue("$userName")
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).elementAt(1).toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $arrayElemAt: [ " + VALUE_LIST_STRING + ", 1] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void concatWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).concat("field").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $concatArrays: [ " + VALUE_LIST_STRING + ", \"$field\"] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void filterWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).filter().as("var").by(new Document())
|
||||
.toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ \"$in\" : [\"$userName\", [\"Shashank\", \"Sharma\"]] }"));
|
||||
.isEqualTo(Document
|
||||
.parse("{ $filter: { \"input\" : " + VALUE_LIST_STRING + ", \"as\" : \"var\", \"cond\" : {} } } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void lengthWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).length().toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $size: [ " + VALUE_LIST_STRING + "] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void sliceWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).slice().itemCount(3).toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $slice: [ " + VALUE_LIST_STRING + ", 3] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void indexOfWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).indexOf("s1p").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $indexOfArray: [ " + VALUE_LIST_STRING + ", \"s1p\"] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void reverseWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).reverse().toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $reverseArray: [ " + VALUE_LIST_STRING + "] } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void zipWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).zipWith("field").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $zip: { \"inputs\": [" + VALUE_LIST_STRING + ", \"$field\"]} } "));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2287
|
||||
public void inWithValueList() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf(VALUE_LIST).containsValue("$userName").toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ \"$in\" : [\"$userName\", " + VALUE_LIST_STRING + "] }"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user