summaryrefslogtreecommitdiff
path: root/jstests/core/timeseries/timeseries_index_collation.js
blob: e8ef56501f38580bdd7144cb6e292f979d0a62e3 (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
/**
 * Tests collation with time-series collections.
 *
 * @tags: [
 *   does_not_support_stepdowns,
 *   does_not_support_transactions,
 *   requires_getmore,
 * ]
 */
(function() {
"use strict";

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

TimeseriesTest.run((insert) => {
    const timeFieldName = 'tm';
    const metaFieldName = 'mm';

    const metadata = ['8', '16', '64', '128'];

    const coll = db.timeseries_index_collation;
    const bucketsColl = db.getCollection('system.buckets.' + coll.getName());

    coll.drop();  // implicitly drops bucketsColl.

    // Compares numeric strings as numbers rather than as strings.
    const numericOrdering = {locale: 'en_US', numericOrdering: true};

    assert.commandWorked(db.createCollection(coll.getName(), {
        timeseries: {timeField: timeFieldName, metaField: metaFieldName},
        collation: numericOrdering
    }));
    assert.contains(bucketsColl.getName(), db.getCollectionNames());

    for (let i = 0; i < metadata.length; ++i) {
        const doc = {_id: i, [timeFieldName]: ISODate(), [metaFieldName]: metadata[i]};
        jsTestLog('Inserting doc ' + i + ': ' + tojson(doc));
        assert.commandWorked(insert(coll, doc), 'failed to insert doc: ' + tojson(doc));
    }

    // Check bucket collection. We are using all unique metadata values so each measurement should
    // be in its own bucket.
    const bucketDocs = bucketsColl.find().toArray();
    assert.eq(metadata.length, bucketDocs.length, bucketDocs);

    // Create an index that should use the default collation, which is {numericOrdering: true}.
    const indexKey = {[metaFieldName]: 1};
    assert.commandWorked(coll.createIndex(indexKey, {name: 'index_numeric'}),
                         'failed to create index: ' + tojson(indexKey));

    const expectedNumericOrdering = metadata;
    const docsNumericOrdering = coll.find().hint('index_numeric').toArray();
    assert.eq(expectedNumericOrdering.length,
              docsNumericOrdering.length,
              'unexpected documents returned from index scan with numeric ordering: ' +
                  tojson(docsNumericOrdering) +
                  ' (expected metadata values: ' + tojson(expectedNumericOrdering) + ')');
    for (let i = 0; i < docsNumericOrdering.length; ++i) {
        assert.eq(expectedNumericOrdering[i],
                  docsNumericOrdering[i][metaFieldName],
                  'Unexpected metadata in doc ' + i +
                      ' (numeric ordering): ' + tojson(docsNumericOrdering));
    }

    // Create an index that does not use the default collation and compares numeric strings
    // lexicographically rather than as numbers.
    assert.commandWorked(
        coll.createIndex(
            indexKey, {name: 'index_string', collation: {locale: 'en_US', numericOrdering: false}}),
        'failed to create index: ' + tojson(indexKey));

    const expectedStringOrdering = ['128', '16', '64', '8'];
    const docsStringOrdering = coll.find().hint('index_string').toArray();
    assert.eq(expectedStringOrdering.length,
              docsStringOrdering.length,
              'unexpected documents returned from index scan with string ordering: ' +
                  tojson(docsStringOrdering));
    for (let i = 0; i < docsNumericOrdering.length; ++i) {
        assert.eq(expectedStringOrdering[i],
                  docsStringOrdering[i][metaFieldName],
                  'Unexpected metadata in doc ' + i +
                      ' (string ordering): ' + tojson(docsStringOrdering));
    }

    // Check that listIndexes returns specs with collation information.
    // Don't assume that no other indexes exist--passthrough suites may create other indexes.
    const indexSpecs = coll.getIndexes();

    const indexSpecsNumeric = indexSpecs.filter(ix => ix.name === 'index_numeric');
    assert.eq(1, indexSpecsNumeric.length, {indexSpecs, indexSpecsNumeric});
    assert.eq(true,
              indexSpecsNumeric[0].collation.numericOrdering,
              'Invalid index spec for index_numeric: ' + tojson(indexSpecsNumeric[0]));

    const indexSpecsString = indexSpecs.filter(ix => ix.name === 'index_string');
    assert.eq(1, indexSpecsString.length, {indexSpecs, indexSpecsString});
    assert.eq(false,
              indexSpecsString[0].collation.numericOrdering,
              'Invalid index spec for index_string: ' + tojson(indexSpecsString[0]));
});
})();