1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/**
* Tests the $between operator in simple form in the match language on unencrypted data.
* @tags: [ requires_fcv_62, multiversion_incompatible ]
*/
(function() {
"use strict";
load('jstests/aggregation/extras/utils.js'); // For assertArrayEq.
load('jstests/libs/analyze_plan.js'); // For getWinningPlan.
const coll = db.between_coll;
coll.drop();
// populate the collection with various values.
let i;
for (i = 0; i < 10; i++) {
assert.commandWorked(coll.insert({v: i, _id: i}));
}
assert.commandWorked(coll.insert({v: NumberLong(4), _id: i++}));
assert.commandWorked(coll.insert({v: NumberDecimal(9.2855), _id: i++}));
let stringVals = ["hello", "world", "galaxy", "apple", "apartment"];
stringVals.forEach(string => {
assert.commandWorked(coll.insert({v: string, _id: i++}));
});
assert.commandWorked(coll.insert({v: [2, 4, 6], _id: i++}));
assert.commandWorked(coll.insert({v: [2, "galaxy", [8]], _id: i++}));
assert.commandWorked(coll.insert({v: ISODate("1998-08-03T20:34:00.000Z"), _id: i++}));
assert.commandWorked(coll.insert({v: ISODate("2022-01-01T00:00:00.000Z"), _id: i++}));
// $between given an array of numbers.
let expected = [{v: 3}, {v: 4}, {v: NumberLong(4)}, {v: 5}, {v: 6}, {v: 7}, {v: 8}, {v: [2, 4, 6]}];
assertArrayEq(
{actual: coll.find({v: {$between: [3, 8]}}).toArray(), expected, fieldsToSkip: ["_id"]});
// $between given an array of dates.
expected = [{v: ISODate("1998-08-03T20:34:00.000Z")}];
assertArrayEq({
actual:
coll.find({
v: {
$between:
[ISODate("1996-02-03T20:34:00.000Z"), ISODate("2000-04-03T20:34:00.000Z")]
}
})
.toArray(),
expected,
fieldsToSkip: ["_id"]
});
// $between nested inide a $not expression.
expected = [
{v: 0},
{v: 1},
{v: 2},
{v: 9},
{v: NumberDecimal(9.2855)},
{v: "hello"},
{v: "world"},
{v: "galaxy"},
{v: "apple"},
{v: "apartment"},
{v: [2, "galaxy", [8]]},
{v: ISODate("1998-08-03T20:34:00.000Z")},
{v: ISODate("2022-01-01T00:00:00.000Z")}
];
assertArrayEq({
actual: coll.find({v: {$not: {$between: [3, 8]}}}).toArray(),
expected,
fieldsToSkip: ["_id"]
});
// $between inline with other expressions.
expected = [{v: 0}, {v: "galaxy"}, {v: "apple"}, {v: "apartment"}, {v: [2, "galaxy", [8]]}];
assertArrayEq({
actual: coll.find({$or: [{v: 0}, {v: {$between: ['a', 'gb']}}]}).toArray(),
expected,
fieldsToSkip: ["_id"]
});
// $between returns empty result.
expected = [];
assertArrayEq({actual: coll.find({v: {$between: [NumberInt(32), {}]}}).toArray(), expected});
// $between uses an index scan with arrays.
coll.createIndex({v: 1});
let betweenExplainArray = coll.find({v: {$between: [2, 5]}}).explain().queryPlanner;
let winningPlan = getWinningPlan(betweenExplainArray);
assert(isIxscan(db, winningPlan));
// $between uses an index scan with the proper bounds without arrays.
coll.dropIndex({v: 1});
assert.commandWorked(coll.deleteOne({v: [2, "galaxy", [8]], _id: 18}));
assert.commandWorked(coll.deleteOne({v: [2, 4, 6], _id: 17}));
coll.createIndex({v: 1});
winningPlan = getWinningPlan(coll.find({v: {$between: [2, 5]}}).explain().queryPlanner);
let stages = getPlanStages(winningPlan, "IXSCAN");
assert(isIxscan(db, winningPlan));
stages.forEach(stage => {
assert.eq({v: ["[2.0, 5.0]"]}, stage.indexBounds);
});
// $between must fail if the array does not have 2 elements in it.
assert.throwsWithCode(() => {
coll.find({v: {$between: [1]}}).toArray();
}, ErrorCodes.FailedToParse);
// $between must fail if the array does not have 2 elements in it.
assert.throwsWithCode(() => {
coll.find({v: {$between: [1, 2, 4]}}).toArray();
}, ErrorCodes.FailedToParse);
// $between must fail if the input is not binData or an array.
assert.throwsWithCode(() => {
coll.find({v: {$between: "apartment"}}).toArray();
}, ErrorCodes.BadValue);
// $between must fail if the input is not binData or an array.
assert.throwsWithCode(() => {
coll.find({v: {$between: NumberDecimal(100.32)}}).toArray();
}, ErrorCodes.BadValue);
})();
|