mirror of https://github.com/mongodb/mongo
146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
/**
|
|
* Tests for the approximate percentile expression semantics.
|
|
* @tags: [
|
|
* requires_fcv_70,
|
|
* ]
|
|
*/
|
|
import {testLargeInput, testLargeNonNumericInput, testWithProject} from "jstests/aggregation/libs/percentiles_util.js";
|
|
|
|
const coll = db[jsTestName()];
|
|
|
|
/**
|
|
* Tests with input as a single expression which evaluates to an array.
|
|
*/
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [0, "non-numeric", 1, 2]},
|
|
percentileSpec: {$percentile: {p: [0.5], input: "$x", method: "approximate"}},
|
|
expectedResult: [1],
|
|
msg: "Non-numeric data in input field which evaluates to an array should be ignored",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [10, 5, 27], x1: 5},
|
|
percentileSpec: {$percentile: {p: [0], input: "$x", method: "approximate"}},
|
|
expectedResult: [5],
|
|
msg: "Minimum percentile",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [0, 1, 2]},
|
|
percentileSpec: {$percentile: {p: [0.5, 0.9, 0.1], input: "$x", method: "approximate"}},
|
|
expectedResult: [1, 2, 0],
|
|
msg: "Multiple percentiles when input field evaluates to an array",
|
|
});
|
|
|
|
/**
|
|
* Tests with input as an array of expressions.
|
|
*/
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: 0, x1: "non-numeric", x2: 1, x3: 2, x4: [2, 2, 2]},
|
|
percentileSpec: {$percentile: {p: [0.5], input: ["$x", "$x1", "$x2", "$x3", "$x4"], method: "approximate"}},
|
|
expectedResult: [1],
|
|
msg: "Non-numeric data in input field passed in as an array should be ignored",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: "non-numeric"},
|
|
percentileSpec: {$percentile: {p: [0.5], input: ["$x"], method: "approximate"}},
|
|
expectedResult: [null],
|
|
msg: "Percentile of completely non-numeric data when input field is an array",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: "non-numeric", x1: "also non-numeric", x2: [1, 2, 3]},
|
|
percentileSpec: {$percentile: {p: [0.5, 0.9], input: ["$x", "$x1", "$x2"], method: "approximate"}},
|
|
expectedResult: [null, null],
|
|
msg: "Multiple percentiles of completely non-numeric data in input field passed as an array",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [-Infinity, Infinity, Infinity, Infinity]},
|
|
percentileSpec: {$percentile: {p: [0.1, 0.5], input: "$x", method: "approximate"}},
|
|
expectedResult: [-Infinity, Infinity],
|
|
msg: "Percentile of all infinities",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [0, "non-numeric", 1, 2, 3, Infinity]},
|
|
percentileSpec: {$percentile: {p: [0.5], input: "$x", method: "approximate"}},
|
|
expectedResult: [2],
|
|
msg: "Rank not that of infinity returns numeric, counts infinity as number",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: 10, x1: 5, x2: 27},
|
|
percentileSpec: {$percentile: {p: [1], input: ["$x", "$x1", "$x2"], method: "approximate"}},
|
|
expectedResult: [27],
|
|
msg: "Maximum percentile",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: 0, x1: 1, x2: 2},
|
|
percentileSpec: {$percentile: {p: [0.5, 0.9, 0.1], input: ["$x", "$x1", "$x2"], method: "approximate"}},
|
|
expectedResult: [1, 2, 0],
|
|
msg: "Multiple percentiles when input field is passed as an array",
|
|
});
|
|
|
|
/**
|
|
* Tests with input as a single expression.
|
|
*/
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: 0, x1: 1, x2: 2},
|
|
percentileSpec: {$percentile: {p: [0.5, 0.9, 0.1], input: "$x", method: "approximate"}},
|
|
expectedResult: [0, 0, 0],
|
|
msg: "Multiple percentiles when single input expression resolves to a numeric scalar",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: 0, x1: "non-numeric", x2: 2},
|
|
percentileSpec: {$percentile: {p: [0.5, 0.9, 0.1], input: "$x1", method: "approximate"}},
|
|
expectedResult: [null, null, null],
|
|
msg: "Multiple percentiles when single input expression resolves to a non-numeric scalar",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [2, 1], y: 3},
|
|
percentileSpec: {
|
|
$percentile: {
|
|
p: [0.5, 0.9],
|
|
input: {$concatArrays: ["$x", [{$add: [42, "$y"]}]]},
|
|
method: "approximate",
|
|
},
|
|
},
|
|
expectedResult: [2, 42 + 3],
|
|
msg: "Input as complex expression",
|
|
});
|
|
|
|
testWithProject({
|
|
coll: coll,
|
|
doc: {x: [2, 3, 1]},
|
|
percentileSpec: {$percentile: {p: "$$ps", input: "$x", method: "approximate"}},
|
|
letSpec: {ps: [0.1, 0.5, 0.9]},
|
|
expectedResult: [1, 2, 3],
|
|
msg: "'p' specified as a variable",
|
|
});
|
|
|
|
/**
|
|
* 'rand()' generates a uniform distribution from [0.0, 1.0] so we can check accuracy of the result
|
|
* in terms of values rather than in terms of rank.
|
|
*/
|
|
testLargeInput(coll, "approximate");
|
|
|
|
testLargeNonNumericInput(coll, "approximate");
|