Me preguntaba si hay forma de forzar una entrada de colección única, pero solo si la entrada no es nula . e Esquema de muestra:
var UsersSchema = new Schema({
name : {type: String, trim: true, index: true, required: true},
email : {type: String, trim: true, index: true, unique: true}
});
"email" en este caso no es obligatorio, pero si se guarda "email" quiero asegurarme de que esta entrada sea única (a nivel de base de datos).
Las entradas vacías parecen tener el valor 'nulo', por lo que cada entrada sin correo electrónico se bloquea con la opción 'única' (si hay un usuario diferente sin correo electrónico).
Ahora mismo lo estoy resolviendo a nivel de aplicación, pero me encantaría guardar esa consulta db.
Gracias
email
campo, no donde realmente tiene un valor denull
. Ver respuesta actualizada.tl; dr
Sí, es posible tener varios documentos con un campo configurado
null
o no definido, mientras se aplican valores "reales" únicos.requisitos :
string
oobject
cuándo nonull
).Si no está interesado en los detalles, no dude en pasar a la
implementation
sección.versión más larga
Para complementar la respuesta de @ Nolan, comenzando con MongoDB v3.2, puede usar un índice único parcial con una expresión de filtro.
La expresión de filtro parcial tiene limitaciones. Solo puede incluir lo siguiente:
Esto significa que
{"yourField"{$ne: null}}
no se puede utilizar la expresión trivial .Sin embargo, asumiendo que su campo siempre usa el mismo tipo , puede usar una
$type
expresión .MongoDB v3.6 agregó soporte para especificar múltiples tipos posibles, que se pueden pasar como una matriz:
lo que significa que permite que el valor sea de varios tipos múltiples cuando no
null
.Por lo tanto, si queremos permitir que el
email
campo del ejemplo siguiente acepte valoresstring
o, digamosbinary data
, una$type
expresión adecuada sería:implementación
mangosta
Puede especificarlo en un esquema de mangosta:
o agregarlo directamente a la colección (que usa el controlador nativo node.js):
driver nativo mongodb
utilizando
collection.createIndex
cáscara de mongodb
usando
db.collection.createIndex
:Esto permitirá insertar varios registros con un
null
correo electrónico, o sin ningún campo de correo electrónico, pero no con la misma cadena de correo electrónico.fuente
unique
ysparse
). Actualicé mi esquema con esta respuesta, eliminé mi índice existente y funcionó como un encanto.Solo una actualización rápida para quienes investigan este tema.
La respuesta seleccionada funcionará, pero es posible que desee considerar el uso de índices parciales en su lugar.
Más doco sobre índices parciales: https://docs.mongodb.com/manual/core/index-partial/
fuente
En realidad, solo se guardará correctamente el primer documento en el que no exista "correo electrónico" como campo. Los guardados posteriores en los que el "correo electrónico" no esté presente fallarán y generarán un error (consulte el fragmento de código a continuación). Por esa razón, consulte la documentación oficial de MongoDB con respecto a los índices únicos y las claves perdidas aquí en http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes .
Por definición, el índice único solo puede permitir que un valor se almacene solo una vez. Si considera nulo como uno de esos valores, solo se puede insertar una vez. Tiene razón en su enfoque al asegurarlo y validarlo a nivel de aplicación. Así es como se puede hacer.
También te puede interesar leer este http://www.mongodb.org/display/DOCS/Querying+and+nulls
fuente