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
|
// @tags: [
// requires_non_retryable_writes,
// sbe_incompatible,
// ]
/**
* Tests for the array-related behavior of the $type query operator.
*/
(function() {
"use strict";
let coll = db.jstest_type_array;
coll.drop();
/**
* Iterates 'cursor' and returns a sorted array of the '_id' fields for the returned documents.
*/
function extractSortedIdsFromCursor(cursor) {
let ids = [];
while (cursor.hasNext()) {
ids.push(cursor.next()._id);
}
return ids.sort();
}
function runTests() {
assert.commandWorked(coll.remove({}));
assert.commandWorked(coll.insert({_id: 1, a: [1, 2, 3]}));
assert.commandWorked(coll.insert({_id: 2, a: [1, "foo", 3]}));
assert.commandWorked(coll.insert({_id: 3, a: []}));
assert.commandWorked(coll.insert({_id: 4, a: [[]]}));
assert.commandWorked(coll.insert({_id: 5, a: [[[]]]}));
assert.commandWorked(coll.insert({_id: 6, a: 1}));
assert.commandWorked(coll.insert({_id: 7, a: "foo"}));
assert.eq([1, 2, 6], extractSortedIdsFromCursor(coll.find({a: {$type: "number"}})));
assert.eq([2, 7], extractSortedIdsFromCursor(coll.find({a: {$type: "string"}})));
assert.eq([1, 2, 3, 4, 5], extractSortedIdsFromCursor(coll.find({a: {$type: "array"}})));
assert.eq([4, 5], extractSortedIdsFromCursor(coll.find({"a.0": {$type: "array"}})));
assert.eq([5], extractSortedIdsFromCursor(coll.find({"a.0.0": {$type: "array"}})));
assert.commandWorked(coll.remove({}));
assert.commandWorked(coll.insert({_id: 0, a: 1}));
assert.commandWorked(coll.insert({_id: 1, a: NumberInt(1)}));
assert.commandWorked(coll.insert({_id: 2, a: NumberLong(1)}));
assert.commandWorked(coll.insert({_id: 3, a: "str"}));
assert.commandWorked(coll.insert({_id: 4, a: []}));
assert.commandWorked(coll.insert({_id: 5, a: [NumberInt(1), "str"]}));
assert.commandWorked(coll.insert({_id: 6}));
// Test that $type fails when given array that contains an element that is neither a string
// nor a number.
assert.throws(() => coll.find({a: {$type: ["string", null]}}).itcount());
assert.throws(() => coll.find({a: {$type: [{}, "string"]}}).itcount());
// Test that $type with an array of types can accept both string aliases and numerical type
// codes. Also verifies matching behavior for arrays and for missing values.
assert.eq([2, 3, 5], extractSortedIdsFromCursor(coll.find({a: {$type: ["long", 2]}})));
// Test $type with an array of types, where one of those types is itself "array".
assert.eq([2, 4, 5], extractSortedIdsFromCursor(coll.find({a: {$type: ["long", "array"]}})));
// Test that duplicate types are allowed in the array.
assert.eq(
[2, 4, 5],
extractSortedIdsFromCursor(coll.find({a: {$type: ["long", "array", "long", "array"]}})));
assert.eq([2, 4, 5],
extractSortedIdsFromCursor(coll.find({a: {$type: ["long", "array", 18, 4]}})));
}
// Verify $type queries both with and without an index.
runTests();
assert.commandWorked(coll.createIndex({a: 1}));
runTests();
}());
|