diff --git a/spec/MongoStorageAdapter.spec.js b/spec/MongoStorageAdapter.spec.js index a607fbc4ea..756b9c427c 100644 --- a/spec/MongoStorageAdapter.spec.js +++ b/spec/MongoStorageAdapter.spec.js @@ -502,6 +502,30 @@ describe_only_db('mongo')('MongoStorageAdapter', () => { expect(schemaAfterDeletion.fields.test).toBeUndefined(); }); + it('should create index with partialFilterExpression', async () => { + const database = Config.get(Parse.applicationId).database; + const adapter = database.adapter; + + const user = new Parse.User(); + user.set('username', 'testuser'); + user.set('password', 'testpass'); + await user.signUp(); + + const schema = await new Parse.Schema('_User').get(); + const partialFilterExpression = { _email_verify_token: { $exists: true } }; + + await adapter.ensureIndex('_User', schema, ['username'], 'partial_username_index', false, { + partialFilterExpression, + sparse: false, + }); + + const indexes = await adapter.getIndexes('_User'); + const createdIndex = indexes.find(idx => idx.name === 'partial_username_index'); + expect(createdIndex).toBeDefined(); + expect(createdIndex.partialFilterExpression).toEqual({ _email_verify_token: { $exists: true } }); + expect(createdIndex.sparse).toBeFalsy(); + }); + if (process.env.MONGODB_TOPOLOGY === 'replicaset') { describe('transactions', () => { const headers = { diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index 3b4cd14058..151264703e 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -800,12 +800,17 @@ export class MongoStorageAdapter implements StorageAdapter { const caseInsensitiveOptions: Object = caseInsensitive ? { collation: MongoCollection.caseInsensitiveCollation() } : {}; + const partialFilterOptions: Object = + options.partialFilterExpression !== undefined + ? { partialFilterExpression: options.partialFilterExpression } + : {}; const indexOptions: Object = { ...defaultOptions, ...caseInsensitiveOptions, ...indexNameOptions, ...ttlOptions, ...sparseOptions, + ...partialFilterOptions, }; return this._adaptiveCollection(className)