diff options
-rw-r--r-- | jstests/aggregation/sources/setWindowFields/integral.js | 61 | ||||
-rw-r--r-- | src/mongo/db/pipeline/window_function/window_function_exec.cpp | 6 |
2 files changed, 64 insertions, 3 deletions
diff --git a/jstests/aggregation/sources/setWindowFields/integral.js b/jstests/aggregation/sources/setWindowFields/integral.js index b0c71f3f9b1..bceedb1463d 100644 --- a/jstests/aggregation/sources/setWindowFields/integral.js +++ b/jstests/aggregation/sources/setWindowFields/integral.js @@ -177,7 +177,8 @@ assert.commandFailedWithCode(db.runCommand({ }), 5423902); -// Test various type of window. Only test the stability not testing the actual result. +// Test various type of document-based window. Only test the stability not testing the actual +// result. coll.drop(); assert.commandWorked(coll.insert([ {x: 0, y: 0}, @@ -201,4 +202,62 @@ documentBounds.forEach(function(bounds) { })); assert.eq(res.cursor.firstBatch.length, 3); }); + +// +// Testing range-based $integral. +// +coll.drop(); +assert.commandWorked(coll.insert([ + {time: ISODate("2020-01-01T00:00:00.000Z"), y: 0.0, integral: 0.002}, + {time: ISODate("2020-01-01T00:00:04.000Z"), y: 2.4, integral: 0.008}, + {time: ISODate("2020-01-01T00:00:10.000Z"), y: 5.6, integral: 0.016}, + {time: ISODate("2020-01-01T00:00:18.000Z"), y: 6.8, integral: 0.010}, +])); + +function runRangeBasedIntegral(bounds) { + return coll + .aggregate([ + { + $setWindowFields: { + sortBy: {time: 1}, + output: { + integral: { + $integral: {input: "$y", outputUnit: "second"}, + window: {range: bounds, unit: "second"} + }, + } + } + }, + {$unset: "_id"}, + ]) + .toArray(); +} + +// Empty window. +assert.sameMembers(runRangeBasedIntegral([-1, -1]), [ + {time: ISODate("2020-01-01T00:00:00.000Z"), y: 0.0, integral: null}, + {time: ISODate("2020-01-01T00:00:04.000Z"), y: 2.4, integral: null}, + {time: ISODate("2020-01-01T00:00:10.000Z"), y: 5.6, integral: null}, + {time: ISODate("2020-01-01T00:00:18.000Z"), y: 6.8, integral: null}, +]); + +// Window contains only one doc. +assert.sameMembers(runRangeBasedIntegral([-2, 0]), [ + {time: ISODate("2020-01-01T00:00:00.000Z"), y: 0.0, integral: 0}, + {time: ISODate("2020-01-01T00:00:04.000Z"), y: 2.4, integral: 0}, + {time: ISODate("2020-01-01T00:00:10.000Z"), y: 5.6, integral: 0}, + {time: ISODate("2020-01-01T00:00:18.000Z"), y: 6.8, integral: 0}, +]); + +// Window contains multiple docs. +assert.sameMembers(runRangeBasedIntegral([-6, 6]), [ + // doc[0] and doc[1] are in the window. + {time: ISODate("2020-01-01T00:00:00.000Z"), y: 0.0, integral: 4.8}, + // doc[0], doc[1] and doc[2] are in the window. + {time: ISODate("2020-01-01T00:00:04.000Z"), y: 2.4, integral: 28.8}, + // doc[1] and doc[2] are in the window. + {time: ISODate("2020-01-01T00:00:10.000Z"), y: 5.6, integral: 24.0}, + // Empty window. + {time: ISODate("2020-01-01T00:00:18.000Z"), y: 6.8, integral: 0.0}, +]); })(); diff --git a/src/mongo/db/pipeline/window_function/window_function_exec.cpp b/src/mongo/db/pipeline/window_function/window_function_exec.cpp index 0f144f930da..2bbb520dfa7 100644 --- a/src/mongo/db/pipeline/window_function/window_function_exec.cpp +++ b/src/mongo/db/pipeline/window_function/window_function_exec.cpp @@ -145,17 +145,19 @@ std::unique_ptr<WindowFunctionExec> WindowFunctionExec::create( part.fieldPath != boost::none && !part.expression); auto sortByExpr = ExpressionFieldPath::createPathFromString( expCtx, part.fieldPath->fullPath(), expCtx->variablesParseState); + + auto inputExpr = translateInputExpression(functionStmt.expr, sortBy); if (stdx::holds_alternative<WindowBounds::Unbounded>(rangeBounds.lower)) { return std::make_unique<WindowFunctionExecNonRemovableRange>( iter, - functionStmt.expr->input(), + inputExpr, std::move(sortByExpr), functionStmt.expr->buildAccumulatorOnly(), bounds); } else { return std::make_unique<WindowFunctionExecRemovableRange>( iter, - functionStmt.expr->input(), + inputExpr, std::move(sortByExpr), functionStmt.expr->buildRemovable(), bounds); |