Skip to content

Commit 5bbe481

Browse files
christophstroblmp911de
authored andcommitted
Add support for $minN aggregation operator.
See #4139 Original pull request: #4182.
1 parent fb39c31 commit 5bbe481

File tree

4 files changed

+57
-5
lines changed

4 files changed

+57
-5
lines changed

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperators.java

+36-5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ public Min min() {
133133
return usesFieldRef() ? Min.minOf(fieldReference) : Min.minOf(expression);
134134
}
135135

136+
/**
137+
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and returns the
138+
* requested number of maximum values.
139+
*
140+
* @return new instance of {@link Max}.
141+
* @since 4.0
142+
*/
143+
public Min min(int numberOfResults) {
144+
return min().limit(numberOfResults);
145+
}
146+
136147
/**
137148
* Creates new {@link AggregationExpression} that takes the associated numeric value expression and calculates the
138149
* population standard deviation of the input values.
@@ -551,7 +562,7 @@ private Min(Object value) {
551562

552563
@Override
553564
protected String getMongoMethod() {
554-
return "$min";
565+
return contains("n") ? "$minN" : "$min";
555566
}
556567

557568
/**
@@ -563,7 +574,7 @@ protected String getMongoMethod() {
563574
public static Min minOf(String fieldReference) {
564575

565576
Assert.notNull(fieldReference, "FieldReference must not be null");
566-
return new Min(asFields(fieldReference));
577+
return new Min(Collections.singletonMap("input", Fields.field(fieldReference)));
567578
}
568579

569580
/**
@@ -575,7 +586,7 @@ public static Min minOf(String fieldReference) {
575586
public static Min minOf(AggregationExpression expression) {
576587

577588
Assert.notNull(expression, "Expression must not be null");
578-
return new Min(Collections.singletonList(expression));
589+
return new Min(Collections.singletonMap("input", expression));
579590
}
580591

581592
/**
@@ -588,7 +599,7 @@ public static Min minOf(AggregationExpression expression) {
588599
public Min and(String fieldReference) {
589600

590601
Assert.notNull(fieldReference, "FieldReference must not be null");
591-
return new Min(append(Fields.field(fieldReference)));
602+
return new Min(appendTo("input", Fields.field(fieldReference)));
592603
}
593604

594605
/**
@@ -601,7 +612,27 @@ public Min and(String fieldReference) {
601612
public Min and(AggregationExpression expression) {
602613

603614
Assert.notNull(expression, "Expression must not be null");
604-
return new Min(append(expression));
615+
return new Min(appendTo("input", expression));
616+
}
617+
618+
/**
619+
* Creates new {@link Min} that returns the given number of minimum values ({@literal $minN}).
620+
* <strong>NOTE</strong>: Cannot be used with more than one {@literal input} value.
621+
*
622+
* @param numberOfResults
623+
* @return new instance of {@link Min}.
624+
*/
625+
public Min limit(int numberOfResults) {
626+
return new Min(append("n", numberOfResults));
627+
}
628+
629+
@Override
630+
public Document toDocument(AggregationOperationContext context) {
631+
632+
if (get("n") == null) {
633+
return toDocument(get("input"), context);
634+
}
635+
return super.toDocument(context);
605636
}
606637

607638
@Override

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java

+2
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ public class MethodReferenceNode extends ExpressionNode {
226226
.mappingParametersTo("n", "output", "sortBy"));
227227
map.put("maxN", mapArgRef().forOperator("$maxN") //
228228
.mappingParametersTo("n", "input"));
229+
map.put("minN", mapArgRef().forOperator("$minN") //
230+
.mappingParametersTo("n", "input"));
229231

230232
// CONVERT OPERATORS
231233
map.put("convert", mapArgRef().forOperator("$convert") //

Diff for: spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AccumulatorOperatorsUnitTests.java

+14
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ void rendersMaxN() {
9494
.isEqualTo(Document.parse("{ $maxN: { n: 3, input : \"$price\" } }"));
9595
}
9696

97+
@Test // GH-4139
98+
void rendersMin() {
99+
100+
assertThat(valueOf("price").min().toDocument(Aggregation.DEFAULT_CONTEXT))
101+
.isEqualTo(Document.parse("{ $min: \"$price\" }"));
102+
}
103+
104+
@Test // GH-4139
105+
void rendersMinN() {
106+
107+
assertThat(valueOf("price").min(3).toDocument(Aggregation.DEFAULT_CONTEXT))
108+
.isEqualTo(Document.parse("{ $minN: { n: 3, input : \"$price\" } }"));
109+
}
110+
97111
static class Jedi {
98112

99113
String name;

Diff for: spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

+5
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,11 @@ void shouldRenderMaxN() {
12091209
assertThat(transform("maxN(3, \"$score\")")).isEqualTo("{ $maxN : { n : 3, input : \"$score\" }}");
12101210
}
12111211

1212+
@Test // GH-4139
1213+
void shouldRenderMinN() {
1214+
assertThat(transform("minN(3, \"$score\")")).isEqualTo("{ $minN : { n : 3, input : \"$score\" }}");
1215+
}
1216+
12121217
private Document transform(String expression, Object... params) {
12131218
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
12141219
}

0 commit comments

Comments
 (0)