Skip to content

Commit 15f6dc9

Browse files
committed
Revert windowed functions changes.
JAVA-3860
1 parent f523d13 commit 15f6dc9

File tree

5 files changed

+40
-307
lines changed

5 files changed

+40
-307
lines changed

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

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -111,60 +111,6 @@ public static <TExpression> WindowOutputField avg(final String path, final TExpr
111111
return simpleParameterWindowFunction(path, "$avg", expression, window);
112112
}
113113

114-
/**
115-
* Builds a window output field of percentiles of the evaluation results of the {@code inExpression}
116-
* over documents in the specified {@code window}. The {@code pExpression} parameter represents an array of
117-
* percentiles of interest, with each element being a numeric value between 0.0 and 1.0 (inclusive).
118-
*
119-
* @param path The output field path.
120-
* @param inExpression The input expression.
121-
* @param pExpression The expression representing a percentiles of interest.
122-
* @param method The method to be used for computing the percentiles.
123-
* @param window The window.
124-
* @param <InExpression> The type of the input expression.
125-
* @param <PExpression> The type of the percentile expression.
126-
* @return The constructed windowed output field.
127-
* @mongodb.driver.manual reference/operator/aggregation/percentile/ $percentile
128-
* @mongodb.server.release 7.0
129-
*/
130-
public static <InExpression, PExpression> WindowOutputField percentile(final String path, final InExpression inExpression,
131-
final PExpression pExpression, final String method,
132-
@Nullable final Window window) {
133-
notNull("path", path);
134-
notNull("inExpression", inExpression);
135-
notNull("pExpression", pExpression);
136-
notNull("method", method);
137-
Map<ParamName, Object> args = new LinkedHashMap<>(3);
138-
args.put(ParamName.INPUT, inExpression);
139-
args.put(ParamName.P_LOWERCASE, pExpression);
140-
args.put(ParamName.METHOD, method);
141-
return compoundParameterWindowFunction(path, "$percentile", args, window);
142-
}
143-
144-
/**
145-
* Builds a window output field representing the median value of the evaluation results of the {@code inExpression}
146-
* over documents in the specified {@code window}.
147-
*
148-
* @param inExpression The input expression.
149-
* @param method The method to be used for computing the median.
150-
* @param window The window.
151-
* @param <InExpression> The type of the input expression.
152-
* @return The constructed windowed output field.
153-
* @mongodb.driver.manual reference/operator/aggregation/median/ $median
154-
* @mongodb.server.release 7.0
155-
*/
156-
public static <InExpression> WindowOutputField median(final String path, final InExpression inExpression,
157-
final String method,
158-
@Nullable final Window window) {
159-
notNull("path", path);
160-
notNull("inExpression", inExpression);
161-
notNull("method", method);
162-
Map<ParamName, Object> args = new LinkedHashMap<>(2);
163-
args.put(ParamName.INPUT, inExpression);
164-
args.put(ParamName.METHOD, method);
165-
return compoundParameterWindowFunction(path, "$median", args, window);
166-
}
167-
168114
/**
169115
* Builds a window output field of the sample standard deviation of the evaluation results of the {@code expression} over the
170116
* {@code window}.
@@ -1067,13 +1013,11 @@ private enum ParamName {
10671013
UNIT("unit"),
10681014
N_UPPERCASE("N"),
10691015
N_LOWERCASE("n"),
1070-
P_LOWERCASE("p"),
10711016
ALPHA("alpha"),
10721017
OUTPUT("output"),
10731018
BY("by"),
10741019
DEFAULT("default"),
1075-
SORT_BY("sortBy"),
1076-
METHOD("method");
1020+
SORT_BY("sortBy");
10771021

10781022
private final String value;
10791023

driver-core/src/test/functional/com/mongodb/client/model/AggregatesFunctionalSpecification.groovy

Lines changed: 39 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,14 +1174,47 @@ class AggregatesFunctionalSpecification extends OperationFunctionalSpecification
11741174
@IgnoreIf({ serverVersionLessThan(5, 2) })
11751175
def '$setWindowFields'(Bson preSortBy, Object partitionBy, Bson sortBy, WindowOutputField output, List<Object> expectedFieldValues) {
11761176
given:
1177-
populateDatabaseWithInitialData()
1178-
1179-
when:
1180-
List<Object> actualFieldValues = aggregateWithWindowFields(partitionBy, sortBy, output, preSortBy)
1177+
ZoneId utc = ZoneId.of(ZoneOffset.UTC.getId())
1178+
getCollectionHelper().drop()
1179+
Document[] original = [
1180+
new Document('partitionId', 1)
1181+
.append('num1', 1)
1182+
.append('num2', -1)
1183+
.append('numMissing', 1)
1184+
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(1), utc)),
1185+
new Document('partitionId', 1)
1186+
.append('num1', 2)
1187+
.append('num2', -2)
1188+
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(2), utc)),
1189+
new Document('partitionId', 2)
1190+
.append('num1', 3)
1191+
.append('num2', -3)
1192+
.append('numMissing', 3)
1193+
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(3), utc))]
1194+
getCollectionHelper().insertDocuments(original)
1195+
List<Bson> stages = [
1196+
setWindowFields(partitionBy, sortBy, output),
1197+
sort(ascending('num1'))
1198+
]
1199+
if (preSortBy != null) {
1200+
stages.add(0, sort(preSortBy))
1201+
}
1202+
List<Document> actual = aggregate(stages)
1203+
List<Object> actualFieldValues = actual.stream()
1204+
.map { doc -> doc.get('result') }
1205+
.collect(toList())
11811206

1182-
then:
1207+
expect:
11831208
actualFieldValues.size() == expectedFieldValues.size()
1184-
assertEquals(actualFieldValues, expectedFieldValues)
1209+
for (int i = 0; i < actualFieldValues.size(); i++) {
1210+
Object actualV = actualFieldValues.get(i)
1211+
Object expectedV = expectedFieldValues.get(i)
1212+
if (actualV instanceof Collection && expectedV instanceof Set) {
1213+
assert ((Collection) actualV).toSet() == expectedV
1214+
} else {
1215+
assert actualV == expectedV
1216+
}
1217+
}
11851218

11861219
where:
11871220
preSortBy | partitionBy | sortBy | output | expectedFieldValues
@@ -1269,36 +1302,6 @@ class AggregatesFunctionalSpecification extends OperationFunctionalSpecification
12691302
.linearFill('result', '$numMissing') | [ 1, 2, 3 ]
12701303
}
12711304

1272-
@IgnoreIf({ serverVersionLessThan(7, 0) })
1273-
def '$setWindowFields with quantiles'(Bson preSortBy, Object partitionBy, Bson sortBy,
1274-
WindowOutputField output, List<Object> expectedFieldValues) {
1275-
given:
1276-
populateDatabaseWithInitialData()
1277-
1278-
when:
1279-
List<Object> actualFieldValues = aggregateWithWindowFields(partitionBy, sortBy, output, preSortBy)
1280-
1281-
then:
1282-
actualFieldValues.size() == expectedFieldValues.size()
1283-
assertEquals(actualFieldValues, expectedFieldValues)
1284-
1285-
where:
1286-
preSortBy | partitionBy | sortBy | output | expectedFieldValues
1287-
null | null | null | WindowOutputFields
1288-
.percentile('result', '$num1', [0.1, 0.9], 'approximate', documents(UNBOUNDED, UNBOUNDED)) |
1289-
[[1.0, 3.0], [1.0, 3.0], [1.0, 3.0]]
1290-
null | null | null | WindowOutputFields
1291-
.percentile('result', '$num1', [0.1, 0.9], 'approximate', null) |
1292-
[[1.0, 3.0], [1.0, 3.0], [1.0, 3.0]]
1293-
null | '$partitionId' | null | WindowOutputFields
1294-
.percentile('result', '$num1', [0.1, 0.9], 'approximate', documents(UNBOUNDED, UNBOUNDED)) |
1295-
[[1.0, 2.0], [1.0, 2.0], [3.0, 3.0]]
1296-
null | null | null | WindowOutputFields
1297-
.median('result', '$num1', 'approximate', documents(UNBOUNDED, UNBOUNDED)) | [2.0, 2.0, 2.0]
1298-
null | '$partitionId' | null | WindowOutputFields
1299-
.median('result', '$num1', 'approximate', documents(UNBOUNDED, UNBOUNDED)) | [1.0, 1.0, 3.0]
1300-
}
1301-
13021305
@IgnoreIf({ serverVersionLessThan(5, 0) })
13031306
def '$setWindowFields with multiple output'() {
13041307
given:
@@ -1436,53 +1439,4 @@ class AggregatesFunctionalSpecification extends OperationFunctionalSpecification
14361439
FillOutputField.locf('field1')) |
14371440
[1, 3, 3]
14381441
}
1439-
1440-
private void assertEquals(List<Object> actualFieldValues, List<Object> expectedFieldValues) {
1441-
for (int i = 0; i < actualFieldValues.size(); i++) {
1442-
Object actualV = actualFieldValues.get(i)
1443-
Object expectedV = expectedFieldValues.get(i)
1444-
if (actualV instanceof Collection && expectedV instanceof Set) {
1445-
assert ((Collection) actualV).toSet() == expectedV
1446-
} else {
1447-
assert actualV == expectedV
1448-
}
1449-
}
1450-
}
1451-
1452-
private populateDatabaseWithInitialData(){
1453-
ZoneId utc = ZoneId.of(ZoneOffset.UTC.getId())
1454-
getCollectionHelper().drop()
1455-
Document[] original = [
1456-
new Document('partitionId', 1)
1457-
.append('num1', 1)
1458-
.append('num2', -1)
1459-
.append('numMissing', 1)
1460-
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(1), utc)),
1461-
new Document('partitionId', 1)
1462-
.append('num1', 2)
1463-
.append('num2', -2)
1464-
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(2), utc)),
1465-
new Document('partitionId', 2)
1466-
.append('num1', 3)
1467-
.append('num2', -3)
1468-
.append('numMissing', 3)
1469-
.append('date', LocalDateTime.ofInstant(Instant.ofEpochSecond(3), utc))]
1470-
getCollectionHelper().insertDocuments(original)
1471-
}
1472-
1473-
private List<Object> aggregateWithWindowFields(partitionBy, Bson sortBy, WindowOutputField output, Bson preSortBy) {
1474-
def actualFieldValues
1475-
def stages = [
1476-
setWindowFields(partitionBy, sortBy, output),
1477-
sort(ascending('num1'))
1478-
]
1479-
if (preSortBy != null) {
1480-
stages.add(0, sort(preSortBy))
1481-
}
1482-
List<Document> actual = aggregate(stages)
1483-
actualFieldValues = actual.stream()
1484-
.map { doc -> doc.get('result') }
1485-
.collect(toList())
1486-
actualFieldValues
1487-
}
14881442
}

driver-core/src/test/unit/com/mongodb/client/model/TestWindowOutputFields.java

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,15 @@
2626
import org.bson.Document;
2727
import org.bson.conversions.Bson;
2828
import org.junit.jupiter.api.Test;
29-
import org.junit.jupiter.params.ParameterizedTest;
30-
import org.junit.jupiter.params.provider.Arguments;
31-
import org.junit.jupiter.params.provider.MethodSource;
3229

3330
import java.util.AbstractMap;
34-
import java.util.ArrayList;
35-
import java.util.Arrays;
3631
import java.util.Collection;
3732
import java.util.Collections;
3833
import java.util.HashMap;
39-
import java.util.List;
4034
import java.util.Map;
4135
import java.util.function.BiFunction;
4236
import java.util.function.Function;
4337
import java.util.function.Supplier;
44-
import java.util.stream.Stream;
4538

4639
import static com.mongodb.assertions.Assertions.assertNotNull;
4740
import static com.mongodb.client.model.Sorts.ascending;
@@ -58,9 +51,6 @@ final class TestWindowOutputFields {
5851
private static final String PATH = "newField";
5952
private static final Bson SORT_BY = ascending("sortByField");
6053
private static final Map.Entry<Integer, BsonValue> INT_EXPR = new AbstractMap.SimpleImmutableEntry<>(1, new BsonInt32(1));
61-
private static final Map.Entry<Object, BsonArray> ARRAY_EXPR =
62-
new AbstractMap.SimpleImmutableEntry<>(Arrays.asList(0.5, 0.9, "$$letValueX"),
63-
new BsonArray(Arrays.asList(new BsonDouble(0.5), new BsonDouble(0.9), new BsonString("$$letValueX"))));
6454
private static final Map.Entry<String, BsonValue> STR_EXPR =
6555
new AbstractMap.SimpleImmutableEntry<>("$fieldToRead", new BsonString("$fieldToRead"));
6656
private static final Map.Entry<Document, BsonDocument> DOC_EXPR = new AbstractMap.SimpleImmutableEntry<>(
@@ -222,111 +212,6 @@ void pick() {
222212
);
223213
}
224214

225-
@ParameterizedTest
226-
@MethodSource("percentileWindowFunctionsSource")
227-
void percentile(final Object inExpressionParameter,
228-
final BsonValue expectedInExpression,
229-
final Object pExpressionParameter,
230-
final BsonValue expectedPExpression,
231-
final Window window) {
232-
String expectedFunctionName = "$percentile";
233-
String method = "approximate";
234-
BsonField expectedWindowOutputField = getExpectedBsonField(expectedFunctionName, expectedInExpression, expectedPExpression,
235-
method, window);
236-
237-
Supplier<String> msg = () -> "expectedFunctionName=" + expectedFunctionName
238-
+ ", path=" + PATH
239-
+ ", InExpression=" + inExpressionParameter
240-
+ ", pExpression=" + pExpressionParameter
241-
+ ", method=" + method
242-
+ ", window=" + window;
243-
244-
assertWindowOutputField(expectedWindowOutputField, WindowOutputFields.percentile(PATH, inExpressionParameter, pExpressionParameter, method, window),
245-
msg);
246-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.percentile(null, inExpressionParameter, pExpressionParameter, method, window), msg);
247-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.percentile(PATH, null, pExpressionParameter, method, window), msg);
248-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.percentile(PATH, inExpressionParameter, null, method, window), msg);
249-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.percentile(PATH, inExpressionParameter, pExpressionParameter, null, window), msg);
250-
}
251-
252-
@ParameterizedTest
253-
@MethodSource("medianWindowFunctionsSource")
254-
void median(final Object inExpressionParameter,
255-
final BsonValue expectedInExpression,
256-
final Window window) {
257-
String expectedFunctionName = "$median";
258-
String method = "approximate";
259-
BsonField expectedWindowOutputField = getExpectedBsonField(expectedFunctionName, expectedInExpression,
260-
null, method, window);
261-
262-
Supplier<String> msg = () -> "expectedFunctionName=" + expectedFunctionName
263-
+ ", path=" + PATH
264-
+ ", InExpression=" + inExpressionParameter
265-
+ ", method=" + method
266-
+ ", window=" + window;
267-
268-
assertWindowOutputField(expectedWindowOutputField, WindowOutputFields.median(PATH, inExpressionParameter, method, window),
269-
msg);
270-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.median(null, inExpressionParameter, method, window),
271-
msg);
272-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.median(PATH, null, method, window), msg);
273-
assertThrows(IllegalArgumentException.class, () -> WindowOutputFields.median(PATH, inExpressionParameter, null, window), msg);
274-
}
275-
276-
private static Stream<Arguments> percentileWindowFunctionsSource() {
277-
Map<Object, BsonValue> inExpressions = new HashMap<>();
278-
inExpressions.put(INT_EXPR.getKey(), INT_EXPR.getValue());
279-
inExpressions.put(STR_EXPR.getKey(), STR_EXPR.getValue());
280-
inExpressions.put(DOC_EXPR.getKey(), DOC_EXPR.getValue());
281-
282-
Map<Object, BsonValue> pExpressions = new HashMap<>();
283-
pExpressions.put(ARRAY_EXPR.getKey(), ARRAY_EXPR.getValue());
284-
pExpressions.put(STR_EXPR.getKey(), STR_EXPR.getValue());
285-
286-
Collection<Window> windows = asList(null, POSITION_BASED_WINDOW, RANGE_BASED_WINDOW);
287-
288-
// Generate different combinations of test arguments using Cartesian product of inExpressions, pExpressions, and windows.
289-
List<Arguments> argumentsList = new ArrayList<>();
290-
inExpressions.forEach((incomingInParameter, inBsonValue) ->
291-
pExpressions.forEach((incomingPParameter, pBsonValue) ->
292-
windows.forEach(window ->
293-
argumentsList.add(
294-
Arguments.of(incomingInParameter, inBsonValue, incomingPParameter, pBsonValue, window)))));
295-
return Stream.of(argumentsList.toArray(new Arguments[]{}));
296-
}
297-
298-
private static Stream<Arguments> medianWindowFunctionsSource() {
299-
Map<Object, BsonValue> inExpressions = new HashMap<>();
300-
inExpressions.put(INT_EXPR.getKey(), INT_EXPR.getValue());
301-
inExpressions.put(STR_EXPR.getKey(), STR_EXPR.getValue());
302-
inExpressions.put(DOC_EXPR.getKey(), DOC_EXPR.getValue());
303-
304-
Collection<Window> windows = asList(null, POSITION_BASED_WINDOW, RANGE_BASED_WINDOW);
305-
306-
// Generate different combinations of test arguments using Cartesian product of inExpressions and windows.
307-
List<Arguments> argumentsList = new ArrayList<>();
308-
inExpressions.forEach((incomingInParameter, inBsonValue) ->
309-
windows.forEach(window ->
310-
argumentsList.add(
311-
Arguments.of(incomingInParameter, inBsonValue, window))));
312-
return Stream.of(argumentsList.toArray(new Arguments[]{}));
313-
}
314-
315-
private static BsonField getExpectedBsonField(final String expectedFunctionName, final BsonValue expectedInExpression,
316-
final @Nullable BsonValue expectedPExpression,
317-
final String method, final @Nullable Window window) {
318-
BsonDocument expectedFunctionDoc = new BsonDocument("input", expectedInExpression);
319-
if (expectedPExpression != null) {
320-
expectedFunctionDoc.append("p", expectedPExpression);
321-
}
322-
expectedFunctionDoc.append("method", new BsonString(method));
323-
BsonDocument expectedFunctionAndWindow = new BsonDocument(expectedFunctionName, expectedFunctionDoc);
324-
if (window != null) {
325-
expectedFunctionAndWindow.append("window", window.toBsonDocument());
326-
}
327-
return new BsonField(PATH, expectedFunctionAndWindow);
328-
}
329-
330215
private static void assertPickNoSortWindowFunction(
331216
final String expectedFunctionName,
332217
final QuadriFunction<String, Object, Object, Window, WindowOutputField> windowOutputFieldBuilder,

0 commit comments

Comments
 (0)