Skip to content

Commit 6a5ee71

Browse files
committed
fix(model): make diffIndexes() avoid trying to drop default timeseries collection index
Fix #14984
1 parent a0fdb9e commit 6a5ee71

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
/**
4+
* Returns `true` if the given index matches the schema's `timestamps` options
5+
*/
6+
7+
module.exports = function isTimeseriesIndex(dbIndex, schemaOptions) {
8+
if (schemaOptions.timeseries == null) {
9+
return false;
10+
}
11+
const { timeField, metaField } = schemaOptions.timeseries;
12+
if (typeof timeField !== 'string' || typeof metaField !== 'string') {
13+
return false;
14+
}
15+
return Object.keys(dbIndex.key).length === 2 && dbIndex.key[timeField] === 1 && dbIndex.key[metaField] === 1;
16+
};

lib/model.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const immediate = require('./helpers/immediate');
5151
const internalToObjectOptions = require('./options').internalToObjectOptions;
5252
const isDefaultIdIndex = require('./helpers/indexes/isDefaultIdIndex');
5353
const isIndexEqual = require('./helpers/indexes/isIndexEqual');
54+
const isTimeseriesIndex = require('./helpers/indexes/isTimeseriesIndex');
5455
const {
5556
getRelatedDBIndexes,
5657
getRelatedSchemaIndexes
@@ -1418,6 +1419,10 @@ function getIndexesToDrop(schema, schemaIndexes, dbIndexes) {
14181419
if (isDefaultIdIndex(dbIndex)) {
14191420
continue;
14201421
}
1422+
// Timeseries collections have a default index on { timeField: 1, metaField: 1 }.
1423+
if (isTimeseriesIndex(dbIndex, schema.options)) {
1424+
continue;
1425+
}
14211426

14221427
for (const [schemaIndexKeysObject, schemaIndexOptions] of schemaIndexes) {
14231428
const options = decorateDiscriminatorIndexOptions(schema, clone(schemaIndexOptions));
@@ -1429,9 +1434,11 @@ function getIndexesToDrop(schema, schemaIndexes, dbIndexes) {
14291434
}
14301435
}
14311436

1432-
if (!found) {
1433-
toDrop.push(dbIndex.name);
1437+
if (found) {
1438+
continue;
14341439
}
1440+
1441+
toDrop.push(dbIndex.name);
14351442
}
14361443

14371444
return toDrop;

test/model.test.js

+40
Original file line numberDiff line numberDiff line change
@@ -8147,6 +8147,46 @@ describe('Model', function() {
81478147
assert.ok(obj.post.updatedAt.valueOf(), new Date('2023-06-01T18:00:00.000Z').valueOf());
81488148
});
81498149
});
8150+
8151+
describe('diffIndexes()', function() {
8152+
it('avoids trying to drop timeseries collections (gh-14984)', async function() {
8153+
const schema = new mongoose.Schema(
8154+
{
8155+
time: {
8156+
type: Date
8157+
},
8158+
deviceId: {
8159+
type: String
8160+
}
8161+
},
8162+
{
8163+
timeseries: {
8164+
timeField: 'time',
8165+
metaField: 'deviceId',
8166+
granularity: 'seconds'
8167+
},
8168+
autoCreate: false
8169+
}
8170+
);
8171+
8172+
const TestModel = db.model(
8173+
'TimeSeriesTest',
8174+
schema,
8175+
'gh14984'
8176+
);
8177+
8178+
await db.dropCollection('gh14984').catch(err => {
8179+
if (err.codeName === 'NamespaceNotFound') {
8180+
return;
8181+
}
8182+
throw err;
8183+
});
8184+
await TestModel.createCollection();
8185+
8186+
const { toDrop } = await TestModel.diffIndexes();
8187+
assert.deepStrictEqual(toDrop, []);
8188+
});
8189+
});
81508190
});
81518191

81528192

0 commit comments

Comments
 (0)