mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +01:00
75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
// SERVER-9625 Making accumulators $sum, $min, $max, $avg, $stdDevSamp, and $stdDevPop available as
|
|
// expressions.
|
|
|
|
// For assertErrorCode.
|
|
load('jstests/aggregation/extras/utils.js');
|
|
|
|
(function() {
|
|
'use strict';
|
|
var coll = db.server9625;
|
|
coll.drop();
|
|
assert.writeOK(coll.insert({}));
|
|
|
|
// Helper for testing that op returns expResult.
|
|
function testOp(op, expResult) {
|
|
var pipeline = [{$project: {_id: 0, result: op}}];
|
|
assert.eq(coll.aggregate(pipeline).toArray(), [{result: expResult}]);
|
|
}
|
|
|
|
// ExpressionFromAccumulators take either a list of arguments or a single array argument.
|
|
testOp({$avg: [1, 2, 3, 4, 5]}, 3);
|
|
testOp({$avg: [[1, 2, 3, 4, 5]]}, 3);
|
|
testOp({$min: [1, 2, 3, 4, 5]}, 1);
|
|
testOp({$min: [[1, 2, 3, 4, 5]]}, 1);
|
|
testOp({$max: [1, 2, 3, 4, 5]}, 5);
|
|
testOp({$max: [[1, 2, 3, 4, 5]]}, 5);
|
|
testOp({$sum: [1, 2, 3, 4, 5]}, 15);
|
|
testOp({$sum: [[1, 2, 3, 4, 5]]}, 15);
|
|
testOp({$stdDevPop: [1, 3]}, 1);
|
|
testOp({$stdDevPop: [[1, 3]]}, 1);
|
|
testOp({$stdDevSamp: [1, 2, 3]}, 1);
|
|
testOp({$stdDevSamp: [[1, 2, 3]]}, 1);
|
|
|
|
// Null arguments are ignored.
|
|
testOp({$avg: [1, 2, 3, 4, 5, null]}, 3);
|
|
testOp({$min: [1, 2, 3, 4, 5, null]}, 1);
|
|
testOp({$max: [1, 2, 3, 4, 5, null]}, 5);
|
|
testOp({$sum: [1, 2, 3, 4, 5, null]}, 15);
|
|
testOp({$stdDevPop: [1, 3, null]}, 1);
|
|
testOp({$stdDevSamp: [1, 2, 3, null]}, 1);
|
|
|
|
// NaN arguments are processed by all expressions.
|
|
testOp({$avg: [1, 2, 3, 4, 5, NaN]}, NaN);
|
|
testOp({$min: [1, 2, 3, 4, 5, NaN]}, NaN);
|
|
testOp({$max: [1, 2, 3, 4, 5, NaN]}, 5);
|
|
testOp({$sum: [1, 2, 3, 4, 5, NaN]}, NaN);
|
|
testOp({$stdDevPop: [1, 3, NaN]}, NaN);
|
|
testOp({$stdDevSamp: [1, 2, 3, NaN]}, NaN);
|
|
|
|
// Use at least one non-constant value in the following tests, to ensure
|
|
// isAssociative() and isCommutative() are called. If all arguments are constant, the
|
|
// optimization will evaluate them all into one, without calling isAssociative() nor
|
|
// isCommutative().
|
|
coll.drop();
|
|
assert.writeOK(coll.insert({"a": 1, "b": 6}));
|
|
|
|
// These expressions are associative and commutative so inner expression can be combined with
|
|
// outer.
|
|
testOp({$sum: ["$a", 2, 3, {$sum: [4, 5]}]}, 15);
|
|
testOp({$min: ["$a", 2, 3, {$min: [4, 5]}]}, 1);
|
|
testOp({$max: ["$a", 2, 3, {$max: [4, 5]}]}, 5);
|
|
|
|
// These expressions are not associative and commutative so inner expression cannot be combined
|
|
// with outer.
|
|
testOp({$avg: ["$a", 3, {$avg: [4, 6]}]}, 3);
|
|
testOp({$stdDevPop: ["$a", {$stdDevPop: [1, 3]}]}, 0);
|
|
testOp({$stdDevSamp: ["$a", {$stdDevSamp: [1, 2, 3]}]}, 0);
|
|
|
|
// If isAssociative() and isCommutative() did not return false when provided a single argument,
|
|
// the single array argument provided to the inner expression would be ignored instead of
|
|
// treated as a list of arguments, and these tests would fail.
|
|
testOp({$sum: ["$a", 2, 3, {$sum: [["$a", 4, 5]]}]}, 16);
|
|
testOp({$min: ["$b", 2, 3, {$min: [["$a", 4, 5]]}]}, 1);
|
|
testOp({$max: ["$a", 2, 3, {$max: [["$b", 4, 5]]}]}, 6);
|
|
}());
|