Estoy tratando de permitir que MongoDB detecte un valor duplicado según su índice. Creo que esto es posible en MongoDB, pero a través de la envoltura de Mongoose las cosas parecen estar rotas. Entonces, para algo como esto:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
Puedo guardar 2 usuarios con el mismo correo electrónico. Maldito.
El mismo problema se ha expresado aquí: https://github.com/LearnBoost/mongoose/issues/56 , pero ese hilo es antiguo y no conduce a ninguna parte.
Por ahora, estoy haciendo una llamada manualmente a la base de datos para encontrar al usuario. Esa llamada no es cara ya que el "correo electrónico" está indexado. Pero aún sería bueno dejar que se manejara de forma nativa.
¿Alguien tiene una solución para esto?
Respuestas:
¡Ups! Solo tienes que reiniciar mongo.
fuente
Y vuelva a indexar también, con:
En las pruebas, como no tengo datos importantes, también puede hacer:
fuente
Me encontré con el mismo problema: agregué la restricción única para el
email
campo a nuestroUserSchema
después de haber agregado usuarios a la base de datos, y aún pude guardar usuarios con correos electrónicos engañados. Resolví esto haciendo lo siguiente:1) Elimine todos los documentos de la colección de usuarios.
2) Desde el shell mongo, ejecute el comando:
db.users.createIndex({email: 1}, {unique: true})
Con respecto al paso 1, tenga en cuenta que de los documentos de Mongo:
https://docs.mongodb.com/manual/core/index-unique/
fuente
Este comportamiento ocurre también si ha dejado algunos duplicados en Mongo. Mongoose intentará crearlos en Mongo cuando se inicie la aplicación.
Para evitar esto, puede manejar este error de esta manera:
yourModel.on('index', function(err) { if (err?) { console.error err } );
fuente
Ok, pude resolver esto desde mongoshell agregando el índice en el campo y estableciendo la propiedad única:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell debería responder de esta manera:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Ahora para probar rápidamente desde el mongoshell:
var doc = {fieldName: 'abc'}; db.<collectionName>.insert(doc)
Debería dar: WriteResult ({"nInserted": 1})
Pero al repetir de nuevo:
Daré:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1 dup key: { : \"[email protected]\" }" } })
fuente
He hecho algo como esto:
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const FooSchema = new Schema({ name: { type: String, required: true, index: true, unique: true } }); const Foo = mongoose.model('Foo', FooSchema); Foo.createIndexes(); module.exports = Foo
Agregué la
Foo.createIndexes()
línea porque recibía la siguiente advertencia de desaprobación cuando se estaba ejecutando el código:(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
No estoy seguro de si
Foo.createIndexes()
es asincrónico, pero AFAIK las cosas parecen estar funcionando bienfuente
index: true
que se creara mi índice único.Según la documentación: https://docs.mongodb.com/v2.6/tutorial/modify-an-index/
¡NO REINICIES MONGO!
1 - suelta la colección
2 - reindexar la tabla
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
fuente
Mongoose es un poco flojo al aplicar índices únicos desde el nivel de la aplicación; por lo tanto, es preferible hacer cumplir sus índices únicos de la base de datos usando el mongo cli o decirle explícitamente a mangosta que se toma en serio el
unique
índice escribiendo la siguiente línea de código justo después de su UserSchema:UserSchema.index({ username: 1, email: 1 }, { unique: true});
Esto aplicará el índice único en ambos campos
username
yemail
en su UserSchema. Salud.fuente
Mongoose fallará silenciosamente al agregar un índice único cuando:
En el primer caso, enumere los índices con
db.collection.getIndexes()
y suelte el índice antiguo condb.collection.dropIndex("index_name")
. Cuando reinicie la aplicación Mongoose, debería agregar correctamente el nuevo índice.En el segundo caso, debe eliminar los duplicados antes de reiniciar la aplicación Mongoose.
fuente
validador-único-mangosta
Cómo utilizar este complemento:
1) npm install --save mongoose-unique-validator
2) en su esquema, siga esta guía:
// declare this at the top var mongoose = require('mongoose'); var uniqueValidator = require('mongoose-unique-validator'); // exampleSchema = mongoose.Schema({}) etc... exampleSchema.plugin(uniqueValidator); // module.exports = mongoose.model(...) etc....
3) métodos de mangosta
Cuando utilice métodos como
findOneAndUpdate
, deberá pasar este objeto de configuración:{ runValidators: true, context: 'query' }
ie. User.findOneAndUpdate( { email: '[email protected]' }, { email: '[email protected]' }, { runValidators: true, context: 'query' }, function(err) { // ... }
4) opciones adicionales
no distingue entre mayúsculas y minúsculas
use la opción uniqueCaseInsensitive en su esquema
ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }
mensajes de error personalizados
ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });
Ahora puede agregar / eliminar la propiedad única a sus esquemas sin preocuparse por reiniciar mongo, eliminar bases de datos o crear índices.
Advertencias (de los documentos):
Debido a que confiamos en operaciones asíncronas para verificar si un documento existe en la base de datos, es posible que se ejecuten dos consultas al mismo tiempo, ambas obtienen 0 y luego ambas se insertan en MongoDB.
Fuera de bloquear automáticamente la colección o forzar una sola conexión, no existe una solución real.
Para la mayoría de nuestros usuarios, esto no será un problema, pero es un caso extremo a tener en cuenta.
fuente
Respuesta más reciente: no hay necesidad de reiniciar mongodb en absoluto, si colleciton ya tiene índices del mismo nombre, mongoose no volverá a crear sus índices, por lo tanto, elimine los índices existentes de colleciton primero, y ahora, cuando ejecute mongoose, creará un nuevo índice , el proceso anterior resolvió mi problema.
fuente
También puede resolver este problema eliminando el índice;
supongamos que desea eliminar el índice único de la colección
users
y el campousername
, escriba esto:db.users.dropIndex('username_1');
fuente
Si la tabla / colección está vacía, cree un índice único para el campo:
db.<collection_name>.createIndex({'field':1}, {unique: true})
Si la tabla / colección no está vacía, suelte la colección y cree un índice:
db.<collection_name>.drop() db.<collection_name>.createIndex({'field':1}, {unique: true})
Ahora reinicie mongoDB.
fuente
compruebe que autoIndex en el esquema sea verdadero, tal vez se establezca falso (predeterminado verdadero) cuando use las opciones de mongoose.connect
fuente
Enfrenté el mismo problema por un tiempo e hice muchas búsquedas y la solución para mí fue la
createIndexes()
función.Deseo que eso ayude.
por lo que el código será así.
User = new Schema ({ email: {type: String, unique: true} }); User.createIndexes();
fuente
Si está utilizando la opción
autoIndex: false
en el método de conexión de esta manera:mongoose.connect(CONNECTION_STRING, { autoIndex: false });
Intenta eliminar eso. Si eso no funciona, intente reiniciar mongodb como se sugiere en este hilo.
fuente
Puede definir su esquema como
User = new Schema ({ email: { type: String, unique: true } })
Pero quizás esto no funcione cuando ya existe un documento y después de eso, ha cambiado el esquema del Usuario. Puede crear un índice en el correo electrónico para esta colección de usuarios si no desea eliminar la colección. Con este comando puede crear un índice en el correo electrónico.
db.User.createIndex({email:1},{unique: true})
O simplemente puede eliminar la colección y agregar el usuario nuevamente.
Para eliminar la colección, puede ingresar esto:
fuente
Cuando encontré este problema, intenté eliminar la base de datos, reiniciar el servidor (nodemon) muchas veces y ninguno de los trucos funcionó en absoluto. Encontré el siguiente trabajo, a través de Robo 3T:
_id_
como predeterminado. Ahora, elija Agregar índiceemail
para el campo de correo electrónico, por ejemploProporcione claves como JSON. Por ejemplo
{ "email": 1 }
Haga clic en la casilla de verificación Único
Esto asegurará que no se guarden correos electrónicos duplicados en MongoDB.
fuente
Asegúrese de que su colección no sea redundante del campo en el que acaba de colocar el índice único.
Luego, simplemente reinicie su aplicación (mangosta). Simplemente agrega silenciosamente el índice falla.
fuente
Eliminar todos los documentos de la colección:
Y un reinicio, como otros mencionaron, funcionó para mí.
fuente
Si su MongoDB está funcionando como un servicio (una forma fácil de encontrar esto es si no necesita conectarse a la base de datos sin iniciar el archivo mongod.exe a través de la terminal), luego de hacer los cambios, es posible que deba reiniciar el servicio y / o elimine completamente su base de datos.
Es bastante extraño porque para algunos usuarios solo funcionó eliminar una sola colección. Algunos de ellos solo necesitaban eliminar la base de datos. Pero esos no funcionaron para mí. Dejé caer la base de datos y luego reinicié el servicio del servidor MongoDB.
Para reiniciar un servicio, busque Servicios en la barra de búsqueda de Windows y luego busque el servicio MongoDB, haga doble clic para abrir, luego detenga e inicie el servicio nuevamente.
Si los otros métodos no le funcionaron, creo que este funcionará.
fuente
En mi caso, la mangosta estaba desactualizada. Lo comprobé ejecutando npm obsoleto en CMD. y actualizado 'mangosta'.
Por favor, diga si eso también le funcionó.
fuente
Cuando conecte su base de datos con la aplicación agregue esta opción: "audoIndex: true" por ejemplo en mi código hice esto:
const options = { // your options go here ... // this code is the solution audoIndex: true } mongoose.connect(DB_URI, options);
También dejé caer la colección con la que tengo problemas y la recreé para asegurarme de que funcionará. Encontré esta solución en: https://dev.to/emmysteven/solved-mongoose-unique-index-not-working-45d5 También probé soluciones como "reiniciar MongoDB" pero no funcionó para mí.
fuente