tl; dr
Sì, è possibile avere più documenti con un campo impostato su nullo non definito, applicando valori "effettivi" univoci.
requisiti :
- MongoDB v3.2 +.
- Conoscere in anticipo il proprio tipo di valore concreto (ad esempio, sempre a
stringo objectquando no null).
Se non sei interessato ai dettagli, non esitare a passare alla implementationsezione.
versione più lunga
Per integrare la risposta di @ Nolan, a partire da MongoDB v3.2 puoi utilizzare un indice univoco parziale con un'espressione di filtro.
L'espressione del filtro parziale ha dei limiti. Può includere solo quanto segue:
- espressioni di uguaglianza (ad es. campo: valore o utilizzando l'
$eqoperatore),
$exists: true espressione,
$gt, $gte, $lt, $lteEspressioni,
$type espressioni,
$and solo operatore di primo livello
Ciò significa che l'espressione banale {"yourField"{$ne: null}}non può essere utilizzata.
Tuttavia, supponendo che il campo utilizzi sempre lo stesso tipo , è possibile utilizzare $typeun'espressione .
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6 ha aggiunto il supporto per specificare più tipi possibili, che possono essere passati come un array:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
il che significa che consente al valore di essere di un numero qualsiasi di più tipi quando non lo è null.
Pertanto, se vogliamo consentire al emailcampo nell'esempio seguente di accettare uno stringo, diciamo, binary datavalori, $typeun'espressione appropriata sarebbe:
{email: {$type: ["string", "binData"]}}
implementazione
mangusta
Puoi specificarlo in uno schema mongoose:
const UsersSchema = new Schema({
name: {type: String, trim: true, index: true, required: true},
email: {
type: String, trim: true, index: {
unique: true,
partialFilterExpression: {email: {$type: "string"}}
}
}
});
o aggiungilo direttamente alla raccolta (che utilizza il driver node.js nativo):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
driver mongodb nativo
utilizzando collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
mongodb shell
utilizzando db.collection.createIndex:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
Ciò consentirà di inserire più record con nullun'e-mail o senza un campo e-mail, ma non con la stessa stringa e-mail.