summaryrefslogtreecommitdiff
path: root/jstests/core/geo_s2twofields.js
blob: 1868287cf5b39afb2762f2453a821737e32c9bee (plain)
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
// Verify that we can index multiple geo fields with 2dsphere, and that
// performance is what we expect it to be with indexing both fields.
var t = db.geo_s2twofields;
t.drop();

Random.setRandomSeed();
var random = Random.rand;
var PI = Math.PI;

function randomCoord(center, minDistDeg, maxDistDeg) {
    var dx = random() * (maxDistDeg - minDistDeg) + minDistDeg;
    var dy = random() * (maxDistDeg - minDistDeg) + minDistDeg;
    return [center[0] + dx, center[1] + dy];
}

var nyc = {
    type: "Point",
    coordinates: [-74.0064, 40.7142]
};
var miami = {
    type: "Point",
    coordinates: [-80.1303, 25.7903]
};
var maxPoints = 10000;
var degrees = 5;

var arr = [];
for (var i = 0; i < maxPoints; ++i) {
    var fromCoord = randomCoord(nyc.coordinates, 0, degrees);
    var toCoord = randomCoord(miami.coordinates, 0, degrees);

    arr.push({
        from: {type: "Point", coordinates: fromCoord},
        to: {type: "Point", coordinates: toCoord}
    });
}
res = t.insert(arr);
assert.writeOK(res);
assert.eq(t.count(), maxPoints);

function semiRigorousTime(func) {
    var lowestTime = func();
    var iter = 2;
    for (var i = 0; i < iter; ++i) {
        var run = func();
        if (run < lowestTime) {
            lowestTime = run;
        }
    }
    return lowestTime;
}

function timeWithoutAndWithAnIndex(index, query) {
    t.dropIndex(index);
    var withoutTime = semiRigorousTime(function() {
        return t.find(query).explain("executionStats").executionStats.executionTimeMillis;
    });
    t.ensureIndex(index);
    var withTime = semiRigorousTime(function() {
        return t.find(query).explain("executionStats").executionStats.executionTimeMillis;
    });
    t.dropIndex(index);
    return [withoutTime, withTime];
}

var maxQueryRad = 0.5 * PI / 180.0;
// When we're not looking at ALL the data, anything indexed should beat not-indexed.
var smallQuery =
    timeWithoutAndWithAnIndex({to: "2dsphere", from: "2dsphere"},
                              {
                                from: {$within: {$centerSphere: [nyc.coordinates, maxQueryRad]}},
                                to: {$within: {$centerSphere: [miami.coordinates, maxQueryRad]}}
                              });
print("Indexed time " + smallQuery[1] + " unindexed " + smallQuery[0]);
// assert(smallQuery[0] > smallQuery[1]);

// Let's just index one field.
var smallQuery =
    timeWithoutAndWithAnIndex({to: "2dsphere"},
                              {
                                from: {$within: {$centerSphere: [nyc.coordinates, maxQueryRad]}},
                                to: {$within: {$centerSphere: [miami.coordinates, maxQueryRad]}}
                              });
print("Indexed time " + smallQuery[1] + " unindexed " + smallQuery[0]);
// assert(smallQuery[0] > smallQuery[1]);

// And the other one.
var smallQuery =
    timeWithoutAndWithAnIndex({from: "2dsphere"},
                              {
                                from: {$within: {$centerSphere: [nyc.coordinates, maxQueryRad]}},
                                to: {$within: {$centerSphere: [miami.coordinates, maxQueryRad]}}
                              });
print("Indexed time " + smallQuery[1] + " unindexed " + smallQuery[0]);
// assert(smallQuery[0] > smallQuery[1]);