improve field deletion in collection (#6823)
* added filter to updateMany when deleting field * added test cases * added changelog entry
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
### master
|
||||
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.3.0...master)
|
||||
- IMPROVE: Optimized deletion of class field from schema by using an index if available to do an index scan instead of a collection scan. [#6815](https://github.com/parse-community/parse-server/issues/6815). Thanks to [Manuel Trezza](https://github.com/mtrezza).
|
||||
|
||||
### 4.3.0
|
||||
[Full Changelog](https://github.com/parse-community/parse-server/compare/4.2.0...4.3.0)
|
||||
|
||||
@@ -351,6 +351,43 @@ describe_only_db('mongo')('MongoStorageAdapter', () => {
|
||||
expect(postIndexPlan.executionStats.executionStages.stage).toBe('FETCH');
|
||||
});
|
||||
|
||||
it('should delete field without index', async () => {
|
||||
const database = Config.get(Parse.applicationId).database;
|
||||
const obj = new Parse.Object('MyObject');
|
||||
obj.set("test", 1);
|
||||
await obj.save();
|
||||
const schemaBeforeDeletion = await new Parse.Schema('MyObject').get();
|
||||
await database.adapter.deleteFields(
|
||||
"MyObject",
|
||||
schemaBeforeDeletion,
|
||||
["test"]
|
||||
);
|
||||
const schemaAfterDeletion = await new Parse.Schema('MyObject').get();
|
||||
expect(schemaBeforeDeletion.fields.test).toBeDefined();
|
||||
expect(schemaAfterDeletion.fields.test).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should delete field with index', async () => {
|
||||
const database = Config.get(Parse.applicationId).database;
|
||||
const obj = new Parse.Object('MyObject');
|
||||
obj.set("test", 1);
|
||||
await obj.save();
|
||||
const schemaBeforeDeletion = await new Parse.Schema('MyObject').get();
|
||||
await database.adapter.ensureIndex(
|
||||
'MyObject',
|
||||
schemaBeforeDeletion,
|
||||
['test']
|
||||
);
|
||||
await database.adapter.deleteFields(
|
||||
"MyObject",
|
||||
schemaBeforeDeletion,
|
||||
["test"]
|
||||
);
|
||||
const schemaAfterDeletion = await new Parse.Schema('MyObject').get();
|
||||
expect(schemaBeforeDeletion.fields.test).toBeDefined();
|
||||
expect(schemaAfterDeletion.fields.test).toBeUndefined();
|
||||
});
|
||||
|
||||
if (
|
||||
semver.satisfies(process.env.MONGODB_VERSION, '>=4.0.4') &&
|
||||
process.env.MONGODB_TOPOLOGY === 'replicaset' &&
|
||||
|
||||
@@ -433,6 +433,11 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
collectionUpdate['$unset'][name] = null;
|
||||
});
|
||||
|
||||
const collectionFilter = { $or: [] };
|
||||
mongoFormatNames.forEach(name => {
|
||||
collectionFilter['$or'].push({ [name]: { $exists: true } });
|
||||
});
|
||||
|
||||
const schemaUpdate = { $unset: {} };
|
||||
fieldNames.forEach((name) => {
|
||||
schemaUpdate['$unset'][name] = null;
|
||||
@@ -440,7 +445,7 @@ export class MongoStorageAdapter implements StorageAdapter {
|
||||
});
|
||||
|
||||
return this._adaptiveCollection(className)
|
||||
.then((collection) => collection.updateMany({}, collectionUpdate))
|
||||
.then((collection) => collection.updateMany(collectionFilter, collectionUpdate))
|
||||
.then(() => this._schemaCollection())
|
||||
.then((schemaCollection) =>
|
||||
schemaCollection.updateSchema(className, schemaUpdate)
|
||||
|
||||
Reference in New Issue
Block a user