tl; dr
Sì, è possibile avere più documenti con un campo impostato su null
o non definito, applicando valori "effettivi" univoci.
requisiti :
- MongoDB v3.2 +.
- Conoscere in anticipo il proprio tipo di valore concreto (ad esempio, sempre a
string
o object
quando no null
).
Se non sei interessato ai dettagli, non esitare a passare alla implementation
sezione.
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'
$eq
operatore),
$exists: true
espressione,
$gt
, $gte
, $lt
, $lte
Espressioni,
$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 $type
un'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 email
campo nell'esempio seguente di accettare uno string
o, diciamo, binary data
valori, $type
un'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 null
un'e-mail o senza un campo e-mail, ma non con la stessa stringa e-mail.