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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/**
* This test ensures that geo indexes can be defined using very large and very small bounds.
* Additionally, this test also randomizes the precision for the geo index specified in
* 'bits' index option. See SERVER-2386.
*/
(function() {
'use strict';
load("jstests/libs/geo_near_random.js");
// Do some random tests (for near queries) with very large and small ranges
let test = new GeoNearRandomTest("geo_small_large");
let bounds = {min: -Math.pow(2, 34), max: Math.pow(2, 34)};
test.insertPts(50, bounds);
printjson(db["geo_small_large"].find().limit(10).toArray());
test.testPt([0, 0]);
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
test = new GeoNearRandomTest("geo_small_large");
bounds = {
min: -Math.pow(2, -34),
max: Math.pow(2, -34)
};
test.insertPts(50, bounds);
printjson(db["geo_small_large"].find().limit(10).toArray());
test.testPt([0, 0]);
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
test.testPt(test.mkPt(undefined, bounds));
// Check that our box and circle queries also work
let scales = [Math.pow(2, 40), Math.pow(2, -40), Math.pow(2, 2), Math.pow(3, -15), Math.pow(3, 15)];
for (let i = 0; i < scales.length; i++) {
const scale = scales[i];
const eps = Math.pow(2, -7) * scale;
const radius = 5 * scale;
const max = 10 * scale;
const min = -max;
const range = max - min;
const bits = 2 + Math.random() * 30;
const t = db.getCollection('geo_small_large_' + i);
t.drop();
assert.commandWorked(t.createIndex({p: "2d"}, {min: min, max: max, bits: bits}));
let outPoints = 0;
let inPoints = 0;
printjson({eps: eps, radius: radius, max: max, min: min, range: range, bits: bits});
// Put a point slightly inside and outside our range
for (let j = 0; j < 2; j++) {
const currRad = (j % 2 == 0 ? radius + eps : radius - eps);
const res = t.insert({p: {x: currRad, y: 0}});
print(res.toString());
}
printjson(t.find().toArray());
assert.eq(
t.count({p: {$within: {$center: [[0, 0], radius]}}}), 1, "Incorrect center points found!");
assert.eq(t.count({p: {$within: {$box: [[-radius, -radius], [radius, radius]]}}}),
1,
"Incorrect box points found!");
let shouldFind = [];
let randoms = [];
for (let j = 0; j < 2; j++) {
const randX = Math.random(); // randoms[j].randX
const randY = Math.random(); // randoms[j].randY
randoms.push({randX: randX, randY: randY});
const x = randX * (range - eps) + eps + min;
const y = randY * (range - eps) + eps + min;
t.insert({p: [x, y]});
if (x * x + y * y > radius * radius) {
// print( "out point ");
// printjson({ x : x, y : y })
outPoints++;
} else {
// print( "in point ");
// printjson({ x : x, y : y })
inPoints++;
shouldFind.push({x: x, y: y, radius: Math.sqrt(x * x + y * y)});
}
}
/*
function printDiff( didFind, shouldFind ){
for( let i = 0; i < shouldFind.length; i++ ){
let beenFound = false;
for( let j = 0; j < didFind.length && !beenFound ; j++ ){
beenFound = shouldFind[i].x == didFind[j].x &&
shouldFind[i].y == didFind[j].y
}
if( !beenFound ){
print( "Could not find: " )
shouldFind[i].inRadius = ( radius - shouldFind[i].radius >= 0 )
printjson( shouldFind[i] )
}
}
}
print( "Finding random pts... ")
let found = t.find( { p : { $within : { $center : [[0, 0], radius ] } } } ).toArray()
let didFind = []
for( let f = 0; f < found.length; f++ ){
//printjson( found[f] )
let x = found[f].p.x != undefined ? found[f].p.x : found[f].p[0]
let y = found[f].p.y != undefined ? found[f].p.y : found[f].p[1]
didFind.push({ x : x, y : y, radius : Math.sqrt( x * x + y * y ) })
}
print( "Did not find but should: ")
printDiff( didFind, shouldFind )
print( "Found but should not have: ")
printDiff( shouldFind, didFind )
*/
assert.eq(t.count({p: {$within: {$center: [[0, 0], radius]}}}),
1 + inPoints,
"Incorrect random center points found!\n" + tojson(randoms));
print("Found " + inPoints + " points in and " + outPoints + " points out.");
const found = t.find({p: {$near: [0, 0], $maxDistance: radius}}).toArray();
let dist = 0;
for (let f = 0; f < found.length; f++) {
let x = found[f].p.x != undefined ? found[f].p.x : found[f].p[0];
let y = found[f].p.y != undefined ? found[f].p.y : found[f].p[1];
print("Dist: x : " + x + " y : " + y + " dist : " + Math.sqrt(x * x + y * y) +
" radius : " + radius);
}
assert.eq(t.count({p: {$near: [0, 0], $maxDistance: radius}}),
1 + inPoints,
"Incorrect random center points found near!\n" + tojson(randoms));
}
})();
|