Je me demandais s'il y avait moyen de forcer une entrée de collection unique mais seulement si l'entrée n'est pas nulle . e Exemple de schéma:
var UsersSchema = new Schema({
name : {type: String, trim: true, index: true, required: true},
email : {type: String, trim: true, index: true, unique: true}
});
«email» dans ce cas n'est pas obligatoire mais si «email» est enregistré, je veux m'assurer que cette entrée est unique (au niveau de la base de données).
Les entrées vides semblent avoir la valeur «null» donc chaque entrée sans email se bloque avec l'option «unique» (s'il y a un autre utilisateur sans email).
En ce moment, je le résolve au niveau de l'application, mais j'aimerais enregistrer cette requête de base de données.
THX
email
champ, pas là où il y a réellement une valeur denull
. Voir la réponse mise à jour.tl; dr
Oui, il est possible d'avoir plusieurs documents avec un champ défini sur
null
ou non défini, tout en appliquant des valeurs «réelles» uniques.exigences :
string
ouobject
quand pasnull
).Si vous n'êtes pas intéressé par les détails, n'hésitez pas à passer à la
implementation
section.version plus longue
Pour compléter la réponse de @ Nolan, à partir de MongoDB v3.2, vous pouvez utiliser un index unique partiel avec une expression de filtre.
L'expression de filtre partiel a des limites. Il ne peut inclure que les éléments suivants:
Cela signifie que l'expression triviale
{"yourField"{$ne: null}}
ne peut pas être utilisée.Cependant, en supposant que votre champ utilise toujours le même type , vous pouvez utiliser une
$type
expression .MongoDB v3.6 a ajouté la prise en charge de la spécification de plusieurs types possibles, qui peuvent être passés sous forme de tableau:
ce qui signifie qu'il permet à la valeur d'être de l'un de plusieurs types multiples si ce n'est pas le cas
null
.Par conséquent, si nous voulons autoriser le
email
champ de l'exemple ci-dessous à accepter l'unestring
ou, par exemple, desbinary data
valeurs, une$type
expression appropriée serait:la mise en oeuvre
mangouste
Vous pouvez le spécifier dans un schéma mangouste:
ou ajoutez-le directement à la collection (qui utilise le pilote node.js natif):
pilote natif mongodb
en utilisant
collection.createIndex
coque mongodb
en utilisant
db.collection.createIndex
:Cela permettra d'insérer plusieurs enregistrements avec un
null
e - mail, ou sans champ e-mail du tout, mais pas avec la même chaîne d'e-mail.la source
unique
etsparse
). J'ai mis à jour mon schéma avec cette réponse, j'ai supprimé mon index existant et cela a fonctionné comme un charme.Juste une mise à jour rapide pour ceux qui recherchent ce sujet.
La réponse sélectionnée fonctionnera, mais vous voudrez peut-être envisager d'utiliser des index partiels à la place.
Plus de doco sur les index partiels: https://docs.mongodb.com/manual/core/index-partial/
la source
En fait, seul le premier document où le champ "email" n'existe pas sera enregistré avec succès. Les sauvegardes suivantes où «e-mail» n'est pas présent échoueront tout en donnant une erreur (voir l'extrait de code ci-dessous). Pour cette raison, consultez la documentation officielle de MongoDB concernant les index uniques et les clés manquantes ici à http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes .
Par définition, un index unique ne peut autoriser qu'une seule valeur à être stockée une seule fois. Si vous considérez null comme l'une de ces valeurs, elle ne peut être insérée qu'une seule fois! Vous avez raison dans votre démarche en l'assurant et en la validant au niveau applicatif. Voilà comment cela peut être fait.
Vous pouvez également lire ceci http://www.mongodb.org/display/DOCS/Querying+and+nulls
la source