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
126
|
//
// Test input validation for geoNear command.
//
var t = db.geonear_cmd_input_validation;
t.drop();
t.ensureIndex({loc: "2dsphere"});
// The test matrix. Some combinations are not supported:
// 2d index and minDistance.
// 2d index and GeoJSON
// 2dsphere index and spherical=false
var indexTypes = ['2d', '2dsphere'],
pointTypes = [
{type: 'Point', coordinates: [0, 0]},
[0, 0]],
sphericalOptions = [true, false],
optionNames = ['minDistance', 'maxDistance'],
badNumbers = [-1, undefined, 'foo'];
indexTypes.forEach(function(indexType) {
t.drop();
t.createIndex({'loc': indexType});
pointTypes.forEach(function(pointType) {
sphericalOptions.forEach(function(spherical) {
optionNames.forEach(function(optionName) {
var isLegacy = Array.isArray(pointType),
pointDescription = (isLegacy ? "legacy coordinates" : "GeoJSON point");
function makeCommand(distance) {
var command = {
geoNear: t.getName(),
near: pointType,
spherical: spherical
};
command[optionName] = distance;
return command;
}
// Unsupported combinations should return errors.
if (
(indexType == '2d' && optionName == 'minDistance') ||
(indexType == '2d' && !isLegacy) ||
(indexType == '2dsphere' && !spherical)
) {
assert.commandFailed(
db.runCommand(makeCommand(1)),
"geoNear with spherical=" + spherical + " and " + indexType
+ " index and " + pointDescription
+ " should've failed."
);
// Stop processing this combination in the test matrix.
return;
}
// This is a supported combination. No error.
assert.commandWorked(db.runCommand({
geoNear: t.getName(),
near: pointType,
spherical: spherical
}));
// No error with min/maxDistance 1.
db.runCommand(makeCommand(1));
var outOfRangeDistances = [];
if (indexType == '2d') {
// maxDistance unlimited; no error.
db.runCommand(makeCommand(1e10));
} else if (isLegacy) {
// Radians can't be more than pi.
outOfRangeDistances.push(Math.PI + 0.1);
} else {
// Meters can't be more than half circumference.
var earthRadiusMeters = 6378.1 * 1000;
outOfRangeDistances.push(Math.PI * earthRadiusMeters + 100);
}
// Try several bad values for min/maxDistance.
badNumbers.concat(outOfRangeDistances).forEach(function(badDistance) {
var msg = (
"geoNear with spherical=" + spherical + " and "
+ pointDescription + " and " + indexType
+ " index should've failed with "
+ optionName + " " + badDistance);
assert.commandFailed(
db.runCommand(makeCommand(badDistance)),
msg);
});
// Bad values for limit / num.
['num', 'limit'].forEach(function(limitOptionName) {
badNumbers.forEach(function(badLimit) {
var msg = (
"geoNear with spherical=" + spherical + " and "
+ pointDescription + " and " + indexType
+ " index should've failed with '"
+ limitOptionName + "' " + badLimit);
var command = makeCommand(1);
command[limitOptionName] = badLimit;
assert.commandFailed(db.runCommand(command), msg);
});
});
// Bad values for distanceMultiplier.
badNumbers.forEach(function(badNumber) {
var msg = (
"geoNear with spherical=" + spherical + " and "
+ pointDescription + " and " + indexType
+ " index should've failed with distanceMultiplier "
+ badNumber);
var command = makeCommand(1);
command['distanceMultiplier'] = badNumber;
assert.commandFailed(db.runCommand(command), msg);
});
});
});
});
});
|