summaryrefslogtreecommitdiff
path: root/jstests/core/timeseries/timeseries_index_spec.js
blob: 109be8f856a5696a8e8216933ab851019fb1c096 (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
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
/**
 * Tests that the original user index definition is stored on the transformed index definition on
 * the buckets collection for newly supported index types. Indexes created directly on the buckets
 * collection do not have an original user index definition and rely on the reverse mapping
 * mechanism.
 *
 * @tags: [
 *     does_not_support_stepdowns,
 *     does_not_support_transactions,
 *     requires_fcv_51,
 *     requires_find_command,
 *     requires_getmore,
 * ]
 */
(function() {
"use strict";

load("jstests/core/timeseries/libs/timeseries.js");

TimeseriesTest.run(() => {
    const collName = "timeseries_index_spec";

    const timeFieldName = "tm";
    const metaFieldName = "mm";

    const coll = db.getCollection(collName);
    const bucketsColl = db.getCollection("system.buckets." + collName);
    coll.drop();

    assert.commandWorked(db.createCollection(
        coll.getName(), {timeseries: {timeField: timeFieldName, metaField: metaFieldName}}));

    const checkIndexSpec = function(spec, userIndex, isDowngradeCompatible) {
        assert(spec.hasOwnProperty("v"));
        assert(spec.hasOwnProperty("name"));
        assert(spec.hasOwnProperty("key"));

        if (userIndex) {
            assert(!spec.hasOwnProperty("originalSpec"));
            return;
        }

        if (!isDowngradeCompatible) {
            assert(spec.hasOwnProperty("originalSpec"));
            assert.eq(spec.v, spec.originalSpec.v);
            assert.eq(spec.name, spec.originalSpec.name);
            assert.neq(spec.key, spec.originalSpec.key);
        } else {
            assert(!spec.hasOwnProperty("originalSpec"));
        }
    };

    const verifyAndDropIndex = function(isDowngradeCompatible) {
        let userIndexes = coll.getIndexes();
        for (const index of userIndexes) {
            checkIndexSpec(index, /*userIndex=*/true, isDowngradeCompatible);
        }

        let bucketIndexes = bucketsColl.getIndexes();
        for (const index of bucketIndexes) {
            checkIndexSpec(index, /*userIndex=*/false, isDowngradeCompatible);
        }

        assert.commandWorked(coll.dropIndexes("*"));
    };

    assert.commandWorked(coll.createIndex({[timeFieldName]: 1}));
    verifyAndDropIndex(/*isDowngradeCompatible=*/true);

    assert.commandWorked(coll.createIndex({[metaFieldName]: 1}));
    verifyAndDropIndex(/*isDowngradeCompatible=*/true);

    assert.commandWorked(coll.createIndex({[timeFieldName]: 1, [metaFieldName]: 1}));
    verifyAndDropIndex(/*isDowngradeCompatible=*/true);

    if (TimeseriesTest.timeseriesMetricIndexesEnabled(db.getMongo())) {
        assert.commandWorked(coll.createIndex({x: 1}));
        verifyAndDropIndex(/*isDowngradeCompatible=*/false);

        assert.commandWorked(coll.createIndex({x: 1}, {partialFilterExpression: {x: {$gt: 5}}}));
        verifyAndDropIndex(/*isDowngradeCompatible=*/false);

        assert.commandWorked(
            coll.createIndex({[timeFieldName]: 1}, {partialFilterExpression: {x: {$gt: 5}}}));
        verifyAndDropIndex(/*isDowngradeCompatible=*/false);

        assert.commandWorked(
            coll.createIndex({[metaFieldName]: 1}, {partialFilterExpression: {x: {$gt: 5}}}));
        verifyAndDropIndex(/*isDowngradeCompatible=*/false);

        assert.commandWorked(
            coll.createIndex({[metaFieldName]: 1, x: 1}, {partialFilterExpression: {x: {$gt: 5}}}));
        verifyAndDropIndex(/*isDowngradeCompatible=*/false);
    }

    // Creating an index directly on the buckets collection is permitted. However, these types of
    // index creations will not have an "originalSpec" field and rely on the reverse mapping
    // mechanism.
    if (TimeseriesTest.timeseriesMetricIndexesEnabled(db.getMongo())) {
        assert.commandWorked(
            bucketsColl.createIndex({"control.min.y": 1, "control.max.y": 1}, {name: "y"}));

        let foundIndex = false;
        let bucketIndexes = bucketsColl.getIndexes();
        for (const index of bucketIndexes) {
            if (index.name == "y") {
                foundIndex = true;
                assert(!index.hasOwnProperty("originalSpec"));
                break;
            }
        }
        assert(foundIndex);

        // Verify that the bucket index can map to a user index.
        foundIndex = false;
        let userIndexes = coll.getIndexes();
        for (const index of userIndexes) {
            if (index.name == "y") {
                foundIndex = true;
                assert(!index.hasOwnProperty("originalSpec"));
                assert.eq(index.key, {y: 1});
                break;
            }
        }
        assert(foundIndex);
    }
});
}());