Consider a collection with the following documents:
{
name: "John Doe",
emails: [
{
value: "[email protected]",
isValid: true,
isPreferred: true
}
]
},
{
name: "John Doe",
emails: [
{
value: "[email protected]",
isValid: false,
isPreferred: false
},
{
value: "[email protected]",
isValid: true,
isPreferred: true
}
]
}
There should be no users with the same valid and preferred emails, so there is a unique index for that:
db.users.createIndex( { "emails.value": 1 }, { name: "loginEmail", unique: true, partialFilterExpression: { "emails.isValid": true, "emails.isPreferred": true } } )
Adding the following email to the first document triggers the unique constraint violation:
{
name: "John Doe",
emails: [
{
value: "[email protected]",
isValid: false,
isPreferred: false
}
]
}
Caused by: com.mongodb.MongoCommandException: Command failed with error 11000 (DuplicateKey): 'E11000 duplicate key error collection: profiles.users index: loginEmail dup key: { emails.value: "[email protected]", emails.isValid: false, emails.isPreferred: false }' on server profiles-db-mongodb.dev:27017. The full response is {"ok": 0.0, "errmsg": "E11000 duplicate key error collection: profiles.users index: loginEmail dup key: { emails.value: "[email protected]", emails.isValid: false, emails.isPreferred: false }", "code": 11000, "codeName": "DuplicateKey", "keyPattern": {"emails.value": 1, "emails.isValid": 1, "emails.isPreferred": 1}, "keyValue": {"emails.value": "[email protected]", "emails.isValid": false, "emails.isPreferred": false}}
As I can understand, this happens because the filter expression is applied to the collection, not to the embedded documents, so although being somewhat counterintuitive and unexpected, the index behaves as described.
My question is how can I ensure partial uniqueness without having false negatives?