Skip to content

Commit 5ab2a4e

Browse files
authored
Add builders for pick-accumulators / window functions (#954)
JAVA-4094
1 parent 695ce52 commit 5ab2a4e

File tree

8 files changed

+1195
-36
lines changed

8 files changed

+1195
-36
lines changed

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

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020
import org.bson.BsonArray;
2121
import org.bson.BsonDocument;
2222
import org.bson.BsonString;
23+
import org.bson.Document;
24+
import org.bson.conversions.Bson;
2325

2426
import java.util.List;
2527

2628
import static java.util.stream.Collectors.toList;
29+
import static org.bson.assertions.Assertions.notNull;
2730

2831
/**
2932
* Builders for accumulators used in the group pipeline stage of an aggregation pipeline.
@@ -78,6 +81,69 @@ public static <TExpression> BsonField first(final String fieldName, final TExpre
7881
return accumulatorOperator("$first", fieldName, expression);
7982
}
8083

84+
/**
85+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
86+
* of values of the given {@code inExpression} computed for the first {@code N} elements within a presorted group,
87+
* where {@code N} is the positive integral value of the {@code nExpression}.
88+
*
89+
* @param fieldName The field computed by the accumulator.
90+
* @param inExpression The input expression.
91+
* @param nExpression The expression limiting the number of produced values.
92+
* @param <InExpression> The type of the input expression.
93+
* @param <NExpression> The type of the limiting expression.
94+
* @return The requested {@link BsonField}.
95+
* @mongodb.driver.manual reference/operator/aggregation/firstN/ $firstN
96+
* @since 4.7
97+
* @mongodb.server.release 5.2
98+
*/
99+
public static <InExpression, NExpression> BsonField firstN(
100+
final String fieldName, final InExpression inExpression, final NExpression nExpression) {
101+
return pickNAccumulator(notNull("fieldName", fieldName), "$firstN",
102+
notNull("inExpression", inExpression), notNull("nExpression", nExpression));
103+
}
104+
105+
/**
106+
* Returns a combination of a computed field and an accumulator that produces
107+
* a value of the given {@code outExpression} computed for the top element within a group
108+
* sorted according to the provided {@code sortBy} specification.
109+
*
110+
* @param fieldName The field computed by the accumulator.
111+
* @param sortBy The {@linkplain Sorts sort specification}. The syntax is identical to the one expected by {@link Aggregates#sort(Bson)}.
112+
* @param outExpression The output expression.
113+
* @param <OutExpression> The type of the output expression.
114+
* @return The requested {@link BsonField}.
115+
* @mongodb.driver.manual reference/operator/aggregation/top/ $top
116+
* @since 4.7
117+
* @mongodb.server.release 5.2
118+
*/
119+
public static <OutExpression> BsonField top(final String fieldName, final Bson sortBy, final OutExpression outExpression) {
120+
return sortingPickAccumulator(notNull("fieldName", fieldName), "$top",
121+
notNull("sortBy", sortBy), notNull("outExpression", outExpression));
122+
}
123+
124+
/**
125+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
126+
* of values of the given {@code outExpression} computed for the top {@code N} elements within a group
127+
* sorted according to the provided {@code sortBy} specification,
128+
* where {@code N} is the positive integral value of the {@code nExpression}.
129+
*
130+
* @param fieldName The field computed by the accumulator.
131+
* @param sortBy The {@linkplain Sorts sort specification}. The syntax is identical to the one expected by {@link Aggregates#sort(Bson)}.
132+
* @param outExpression The output expression.
133+
* @param nExpression The expression limiting the number of produced values.
134+
* @param <OutExpression> The type of the output expression.
135+
* @param <NExpression> The type of the limiting expression.
136+
* @return The requested {@link BsonField}.
137+
* @mongodb.driver.manual reference/operator/aggregation/topN/ $topN
138+
* @since 4.7
139+
* @mongodb.server.release 5.2
140+
*/
141+
public static <OutExpression, NExpression> BsonField topN(
142+
final String fieldName, final Bson sortBy, final OutExpression outExpression, final NExpression nExpression) {
143+
return sortingPickNAccumulator(notNull("fieldName", fieldName), "$topN",
144+
notNull("sortBy", sortBy), notNull("outExpression", outExpression), notNull("nExpression", nExpression));
145+
}
146+
81147
/**
82148
* Gets a field name for a $group operation representing the value of the given expression when applied to the last member of
83149
* the group.
@@ -92,6 +158,69 @@ public static <TExpression> BsonField last(final String fieldName, final TExpres
92158
return accumulatorOperator("$last", fieldName, expression);
93159
}
94160

161+
/**
162+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
163+
* of values of the given {@code inExpression} computed for the last {@code N} elements within a presorted group,
164+
* where {@code N} is the positive integral value of the {@code nExpression}.
165+
*
166+
* @param fieldName The field computed by the accumulator.
167+
* @param inExpression The input expression.
168+
* @param nExpression The expression limiting the number of produced values.
169+
* @param <InExpression> The type of the input expression.
170+
* @param <NExpression> The type of the limiting expression.
171+
* @return The requested {@link BsonField}.
172+
* @mongodb.driver.manual reference/operator/aggregation/lastN/ $lastN
173+
* @since 4.7
174+
* @mongodb.server.release 5.2
175+
*/
176+
public static <InExpression, NExpression> BsonField lastN(
177+
final String fieldName, final InExpression inExpression, final NExpression nExpression) {
178+
return pickNAccumulator(notNull("fieldName", fieldName), "$lastN",
179+
notNull("inExpression", inExpression), notNull("nExpression", nExpression));
180+
}
181+
182+
/**
183+
* Returns a combination of a computed field and an accumulator that produces
184+
* a value of the given {@code outExpression} computed for the bottom element within a group
185+
* sorted according to the provided {@code sortBy} specification.
186+
*
187+
* @param fieldName The field computed by the accumulator.
188+
* @param sortBy The {@linkplain Sorts sort specification}. The syntax is identical to the one expected by {@link Aggregates#sort(Bson)}.
189+
* @param outExpression The output expression.
190+
* @param <OutExpression> The type of the output expression.
191+
* @return The requested {@link BsonField}.
192+
* @mongodb.driver.manual reference/operator/aggregation/bottom/ $bottom
193+
* @since 4.7
194+
* @mongodb.server.release 5.2
195+
*/
196+
public static <OutExpression> BsonField bottom(final String fieldName, final Bson sortBy, final OutExpression outExpression) {
197+
return sortingPickAccumulator(notNull("fieldName", fieldName), "$bottom",
198+
notNull("sortBy", sortBy), notNull("outExpression", outExpression));
199+
}
200+
201+
/**
202+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
203+
* of values of the given {@code outExpression} computed for the bottom {@code N} elements within a group
204+
* sorted according to the provided {@code sortBy} specification,
205+
* where {@code N} is the positive integral value of the {@code nExpression}.
206+
*
207+
* @param fieldName The field computed by the accumulator.
208+
* @param sortBy The {@linkplain Sorts sort specification}. The syntax is identical to the one expected by {@link Aggregates#sort(Bson)}.
209+
* @param outExpression The output expression.
210+
* @param nExpression The expression limiting the number of produced values.
211+
* @param <OutExpression> The type of the output expression.
212+
* @param <NExpression> The type of the limiting expression.
213+
* @return The requested {@link BsonField}.
214+
* @mongodb.driver.manual reference/operator/aggregation/bottomN/ $bottomN
215+
* @since 4.7
216+
* @mongodb.server.release 5.2
217+
*/
218+
public static <OutExpression, NExpression> BsonField bottomN(
219+
final String fieldName, final Bson sortBy, final OutExpression outExpression, final NExpression nExpression) {
220+
return sortingPickNAccumulator(notNull("fieldName", fieldName), "$bottomN",
221+
notNull("sortBy", sortBy), notNull("outExpression", outExpression), notNull("nExpression", nExpression));
222+
}
223+
95224
/**
96225
* Gets a field name for a $group operation representing the maximum of the values of the given expression when applied to all
97226
* members of the group.
@@ -106,6 +235,27 @@ public static <TExpression> BsonField max(final String fieldName, final TExpress
106235
return accumulatorOperator("$max", fieldName, expression);
107236
}
108237

238+
/**
239+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
240+
* of {@code N} largest values of the given {@code inExpression},
241+
* where {@code N} is the positive integral value of the {@code nExpression}.
242+
*
243+
* @param fieldName The field computed by the accumulator.
244+
* @param inExpression The input expression.
245+
* @param nExpression The expression limiting the number of produced values.
246+
* @param <InExpression> The type of the input expression.
247+
* @param <NExpression> The type of the limiting expression.
248+
* @return The requested {@link BsonField}.
249+
* @mongodb.driver.manual reference/operator/aggregation/maxN/ $maxN
250+
* @since 4.7
251+
* @mongodb.server.release 5.2
252+
*/
253+
public static <InExpression, NExpression> BsonField maxN(
254+
final String fieldName, final InExpression inExpression, final NExpression nExpression) {
255+
return pickNAccumulator(notNull("fieldName", fieldName), "$maxN",
256+
notNull("inExpression", inExpression), notNull("nExpression", nExpression));
257+
}
258+
109259
/**
110260
* Gets a field name for a $group operation representing the minimum of the values of the given expression when applied to all
111261
* members of the group.
@@ -120,6 +270,27 @@ public static <TExpression> BsonField min(final String fieldName, final TExpress
120270
return accumulatorOperator("$min", fieldName, expression);
121271
}
122272

273+
/**
274+
* Returns a combination of a computed field and an accumulator that produces a BSON {@link org.bson.BsonType#ARRAY Array}
275+
* of {@code N} smallest values of the given {@code inExpression},
276+
* where {@code N} is the positive integral value of the {@code nExpression}.
277+
*
278+
* @param fieldName The field computed by the accumulator.
279+
* @param inExpression The input expression.
280+
* @param nExpression The expression limiting the number of produced values.
281+
* @param <InExpression> The type of the input expression.
282+
* @param <NExpression> The type of the limiting expression.
283+
* @return The requested {@link BsonField}.
284+
* @mongodb.driver.manual reference/operator/aggregation/minN/ $minN
285+
* @since 4.7
286+
* @mongodb.server.release 5.2
287+
*/
288+
public static <InExpression, NExpression> BsonField minN(
289+
final String fieldName, final InExpression inExpression, final NExpression nExpression) {
290+
return pickNAccumulator(notNull("fieldName", fieldName), "$minN",
291+
notNull("inExpression", inExpression), notNull("nExpression", nExpression));
292+
}
293+
123294
/**
124295
* Gets a field name for a $group operation representing an array of all values that results from applying an expression to each
125296
* document in a group of documents that share the same group by key.
@@ -321,6 +492,24 @@ private static <TExpression> BsonField accumulatorOperator(final String name, fi
321492
return new BsonField(fieldName, new SimpleExpression<TExpression>(name, expression));
322493
}
323494

495+
private static <InExpression, NExpression> BsonField pickNAccumulator(
496+
final String fieldName, final String accumulatorName, final InExpression inExpression, final NExpression nExpression) {
497+
return new BsonField(fieldName, new Document(accumulatorName, new Document("input", inExpression).append("n", nExpression)));
498+
}
499+
500+
private static <OutExpression> BsonField sortingPickAccumulator(
501+
final String fieldName, final String accumulatorName, final Bson sort, final OutExpression outExpression) {
502+
return new BsonField(fieldName, new Document(accumulatorName, new Document("sortBy", sort).append("output", outExpression)));
503+
}
504+
505+
private static <OutExpression, NExpression> BsonField sortingPickNAccumulator(
506+
final String fieldName, final String accumulatorName,
507+
final Bson sort, final OutExpression outExpression, final NExpression nExpression) {
508+
return new BsonField(fieldName, new Document(accumulatorName, new Document("sortBy", sort)
509+
.append("output", outExpression)
510+
.append("n", nExpression)));
511+
}
512+
324513
private Accumulators() {
325514
}
326515
}

0 commit comments

Comments
 (0)