Skip to content

Commit 1ce4912

Browse files
committed
Replace reduce with individual reductions (#1053)
JAVA-4814
1 parent 3dcd2ff commit 1ce4912

File tree

4 files changed

+290
-57
lines changed

4 files changed

+290
-57
lines changed

driver-core/src/main/com/mongodb/client/model/expressions/ArrayExpression.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.mongodb.client.model.expressions;
1818

19-
import java.util.function.BinaryOperator;
2019
import java.util.function.Function;
2120

2221
import static com.mongodb.client.model.expressions.Expressions.of;
@@ -51,28 +50,51 @@ public interface ArrayExpression<T extends Expression> extends Expression {
5150
*/
5251
<R extends Expression> ArrayExpression<R> map(Function<? super T, ? extends R> in);
5352

53+
IntegerExpression size();
54+
55+
BooleanExpression any(Function<? super T, BooleanExpression> predicate);
56+
57+
BooleanExpression all(Function<? super T, BooleanExpression> predicate);
58+
59+
NumberExpression sum(Function<? super T, ? extends NumberExpression> mapper);
60+
61+
NumberExpression multiply(Function<? super T, ? extends NumberExpression> mapper);
62+
63+
T max(T other);
64+
65+
T min(T other);
66+
67+
ArrayExpression<T> maxN(IntegerExpression n);
68+
ArrayExpression<T> minN(IntegerExpression n);
69+
70+
StringExpression join(Function<? super T, StringExpression> mapper);
71+
72+
<R extends Expression> ArrayExpression<R> concat(Function<? super T, ? extends ArrayExpression<? extends R>> mapper);
73+
74+
<R extends Expression> ArrayExpression<R> union(Function<? super T, ? extends ArrayExpression<? extends R>> mapper);
75+
5476
/**
55-
* Performs a reduction on the elements of this array, using the provided
56-
* identity value and an associative reducing function, and returns
57-
* the reduced value. The initial value must be the identity value for the
58-
* reducing function.
77+
* user asserts that i is in bounds for the array
5978
*
60-
* @param initialValue the identity for the reducing function
61-
* @param in the associative reducing function
62-
* @return the reduced value
79+
* @param i
80+
* @return
6381
*/
64-
T reduce(T initialValue, BinaryOperator<T> in);
65-
66-
IntegerExpression size();
67-
6882
T elementAt(IntegerExpression i);
6983

7084
default T elementAt(final int i) {
7185
return this.elementAt(of(i));
7286
}
7387

88+
/**
89+
* user asserts that array is not empty
90+
* @return
91+
*/
7492
T first();
7593

94+
/**
95+
* user asserts that array is not empty
96+
* @return
97+
*/
7698
T last();
7799

78100
BooleanExpression contains(T contains);

driver-core/src/main/com/mongodb/client/model/expressions/DocumentExpression.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.mongodb.client.model.expressions;
1818

1919
import org.bson.conversions.Bson;
20-
import org.bson.types.Decimal128;
2120

2221
import java.time.Instant;
2322

@@ -47,12 +46,8 @@ default BooleanExpression getBoolean(final String fieldName, final boolean other
4746

4847
NumberExpression getNumber(String fieldName, NumberExpression other);
4948

50-
default NumberExpression getNumber(final String fieldName, final double other) {
51-
return getNumber(fieldName, of(other));
52-
}
53-
54-
default NumberExpression getNumber(final String fieldName, final Decimal128 other) {
55-
return getNumber(fieldName, of(other));
49+
default NumberExpression getNumber(final String fieldName, final Number other) {
50+
return getNumber(fieldName, Expressions.numberToExpression(other));
5651
}
5752

5853
IntegerExpression getInteger(String fieldName);

driver-core/src/main/com/mongodb/client/model/expressions/MqlExpression.java

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.bson.BsonArray;
2020
import org.bson.BsonDocument;
21+
import org.bson.BsonInt32;
2122
import org.bson.BsonString;
2223
import org.bson.BsonValue;
2324
import org.bson.codecs.configuration.CodecRegistry;
@@ -385,7 +386,12 @@ public ArrayExpression<T> filter(final Function<? super T, ? extends BooleanExpr
385386
.append("cond", extractBsonValue(cr, cond.apply(varThis)))));
386387
}
387388

388-
@Override
389+
public ArrayExpression<T> sort() {
390+
return new MqlExpression<>((cr) -> astDoc("$sortArray", new BsonDocument()
391+
.append("input", this.toBsonValue(cr))
392+
.append("sortBy", new BsonInt32(1))));
393+
}
394+
389395
public T reduce(final T initialValue, final BinaryOperator<T> in) {
390396
T varThis = variable("$$this");
391397
T varValue = variable("$$value");
@@ -395,6 +401,77 @@ public T reduce(final T initialValue, final BinaryOperator<T> in) {
395401
.append("in", extractBsonValue(cr, in.apply(varValue, varThis)))));
396402
}
397403

404+
@Override
405+
public BooleanExpression any(final Function<? super T, BooleanExpression> predicate) {
406+
MqlExpression<BooleanExpression> array = (MqlExpression<BooleanExpression>) this.map(predicate);
407+
return array.reduce(of(false), (a, b) -> a.or(b));
408+
}
409+
410+
@Override
411+
public BooleanExpression all(final Function<? super T, BooleanExpression> predicate) {
412+
MqlExpression<BooleanExpression> array = (MqlExpression<BooleanExpression>) this.map(predicate);
413+
return array.reduce(of(true), (a, b) -> a.and(b));
414+
}
415+
416+
@SuppressWarnings("unchecked")
417+
@Override
418+
public NumberExpression sum(final Function<? super T, ? extends NumberExpression> mapper) {
419+
// no sum that returns IntegerExpression, both have same erasure
420+
MqlExpression<NumberExpression> array = (MqlExpression<NumberExpression>) this.map(mapper);
421+
return array.reduce(of(0), (a, b) -> a.add(b));
422+
}
423+
424+
@SuppressWarnings("unchecked")
425+
@Override
426+
public NumberExpression multiply(final Function<? super T, ? extends NumberExpression> mapper) {
427+
MqlExpression<NumberExpression> array = (MqlExpression<NumberExpression>) this.map(mapper);
428+
return array.reduce(of(0), (NumberExpression a, NumberExpression b) -> a.multiply(b));
429+
}
430+
431+
@Override
432+
public T max(final T other) {
433+
return this.size().eq(of(0)).cond(other, this.maxN(of(1)).first());
434+
}
435+
436+
@Override
437+
public T min(final T other) {
438+
return this.size().eq(of(0)).cond(other, this.minN(of(1)).first());
439+
}
440+
441+
@Override
442+
public ArrayExpression<T> maxN(final IntegerExpression n) {
443+
return newMqlExpression((CodecRegistry cr) -> astDoc("$maxN", new BsonDocument()
444+
.append("input", extractBsonValue(cr, this))
445+
.append("n", extractBsonValue(cr, n))));
446+
}
447+
448+
@Override
449+
public ArrayExpression<T> minN(final IntegerExpression n) {
450+
return newMqlExpression((CodecRegistry cr) -> astDoc("$minN", new BsonDocument()
451+
.append("input", extractBsonValue(cr, this))
452+
.append("n", extractBsonValue(cr, n))));
453+
}
454+
455+
@Override
456+
public StringExpression join(final Function<? super T, StringExpression> mapper) {
457+
MqlExpression<StringExpression> array = (MqlExpression<StringExpression>) this.map(mapper);
458+
return array.reduce(of(""), (a, b) -> a.concat(b));
459+
}
460+
461+
@SuppressWarnings("unchecked")
462+
@Override
463+
public <R extends Expression> ArrayExpression<R> concat(final Function<? super T, ? extends ArrayExpression<? extends R>> mapper) {
464+
MqlExpression<ArrayExpression<R>> array = (MqlExpression<ArrayExpression<R>>) this.map(mapper);
465+
return array.reduce(Expressions.ofArray(), (a, b) -> a.concat(b));
466+
}
467+
468+
@SuppressWarnings("unchecked")
469+
@Override
470+
public <R extends Expression> ArrayExpression<R> union(final Function<? super T, ? extends ArrayExpression<? extends R>> mapper) {
471+
MqlExpression<ArrayExpression<R>> array = (MqlExpression<ArrayExpression<R>>) this.map(mapper);
472+
return array.reduce(Expressions.ofArray(), (a, b) -> a.union(b));
473+
}
474+
398475
@Override
399476
public IntegerExpression size() {
400477
return new MqlExpression<>(astWrapped("$size"));

0 commit comments

Comments
 (0)