Я пытаюсь позволить MongoDB обнаруживать повторяющееся значение на основе его индекса. Я думаю, что это возможно в MongoDB, но через оболочку Mongoose что-то ломается. Итак, примерно так:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
Я могу сохранить двух пользователей с одним и тем же адресом электронной почты. Штопать.
Та же проблема была выражена здесь: https://github.com/LearnBoost/mongoose/issues/56 , но эта ветка устарела и ведет в никуда.
На данный момент я вручную вызываю базу данных, чтобы найти пользователя. Этот звонок недорогой, так как "электронная почта" индексируется. Но все равно было бы неплохо, если бы с этим справились изначально.
У кого-нибудь есть решение этого?
Ответы:
Ой! Вам просто нужно перезапустить mongo.
источник
И переиндексируйте тоже:
В процессе тестирования, поскольку у меня нет важных данных, вы также можете:
источник
Я столкнулся с той же проблемой: я добавил уникальное ограничение для
email
поля в нашUserSchema
после того, как уже добавил пользователей в базу данных, и все еще мог сохранять пользователей с дублирующими электронными письмами. Я решил это, выполнив следующие действия:1) Удалите все документы из коллекции пользователей.
2) В оболочке mongo выполните команду:
db.users.createIndex({email: 1}, {unique: true})
Что касается шага 1, обратите внимание, что из документов Mongo:
https://docs.mongodb.com/manual/core/index-unique/
источник
Такое поведение происходит также, если вы оставили несколько дубликатов в Mongo. Mongoose попытается создать их в Mongo при запуске вашего приложения.
Чтобы предотвратить это, вы можете обработать эту ошибку следующим образом:
yourModel.on('index', function(err) { if (err?) { console.error err } );
источник
Хорошо, я смог решить это из mongoshell, добавив индекс в поле и установив уникальное свойство:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell должен ответить следующим образом:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Теперь быстро протестируем из mongoshell:
var doc = {fieldName: 'abc'}; db.<collectionName>.insert(doc)
Должен дать: WriteResult ({"nInserted": 1})
Но если повторить еще раз:
Дам:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1 dup key: { : \"martyna@martycud.com\" }" } })
источник
Я сделал что-то вроде этого:
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
Я добавил
Foo.createIndexes()
строку bc и получал следующее предупреждение об устаревании при запуске кода:(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
Я не уверен, что
Foo.createIndexes()
это асинхронно, но, похоже, все работает нормально.источник
index: true
создание моего уникального индекса.Согласно документации: https://docs.mongodb.com/v2.6/tutorial/modify-an-index/
НЕ ПЕРЕЗАПУСКАТЬ MONGO!
1 - сбросить коллекцию
2 - переиндексировать таблицу
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
источник
Mongoose немного свободен при применении уникальных индексов на уровне приложения; поэтому желательно либо принудительно использовать ваши уникальные индексы из самой базы данных с помощью mongo cli, либо явно сообщить mongoose, что вы серьезно относитесь к
unique
индексу, написав следующую строку кода сразу после вашей UserSchema:UserSchema.index({ username: 1, email: 1 }, { unique: true});
Это будет обеспечивать уникальный индекс на обоих
username
иemail
полей в вашем UserSchema. Ура.источник
Mongoose автоматически не сможет добавить уникальный индекс, если:
В первом случае укажите индексы с помощью
db.collection.getIndexes()
и отбросьте старый индекс с помощьюdb.collection.dropIndex("index_name")
. Когда вы перезапустите приложение Mongoose, оно должно правильно добавить новый index.Во втором случае вам нужно удалить дубликаты перед перезапуском приложения Mongoose.
источник
мангуст-уникальный-валидатор
Как использовать этот плагин:
1) npm install --save mongoose-unique-validator
2) в своей схеме следуйте этому руководству:
// 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) методы мангуста
При использовании таких методов, как
findOneAndUpdate
вам нужно будет передать этот объект конфигурации:{ runValidators: true, context: 'query' }
ie. User.findOneAndUpdate( { email: 'old-email@example.com' }, { email: 'new-email@example.com' }, { runValidators: true, context: 'query' }, function(err) { // ... }
4) дополнительные опции
без учета регистра
используйте опцию uniqueCaseInsensitive в своей схеме
ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }
пользовательские сообщения об ошибках
ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });
Теперь вы можете добавлять / удалять уникальное свойство в свои схемы, не беспокоясь о перезапуске mongo, удалении баз данных или создании индексов.
Предостережения (из документов):
Поскольку мы полагаемся на асинхронные операции для проверки наличия документа в базе данных, два запроса могут выполняться одновременно, оба возвращают 0, а затем оба вставляются в MongoDB.
Помимо автоматической блокировки коллекции или принудительного установления единственного соединения, настоящего решения нет.
Для большинства наших пользователей это не будет проблемой, но это крайний случай, о котором следует знать.
источник
Самый новый ответ: нет необходимости перезапускать mongodb вообще, если у Colleciton уже есть индексы с тем же именем, mongoose не будет воссоздавать ваши индексы снова, поэтому сначала удалите существующие индексы Colleciton, а теперь, когда вы запустите mongoose, он создаст новый индекс , вышеупомянутый процесс решил мою проблему.
источник
Вы также можете решить эту проблему, отбросив индекс;
Предположим, вы хотите удалить уникальный индекс из коллекции
users
и поляusername
, введите следующее:db.users.dropIndex('username_1');
источник
Если таблица / коллекция пуста, создайте уникальный индекс для поля:
db.<collection_name>.createIndex({'field':1}, {unique: true})
Если таблица / коллекция не пуста, отбросьте коллекцию и создайте индекс:
db.<collection_name>.drop() db.<collection_name>.createIndex({'field':1}, {unique: true})
Теперь перезапустите mongoDB.
источник
проверьте, что autoIndex в схеме истинен, он может установить false (по умолчанию true), когда вы используете параметры mongoose.connect
источник
Некоторое время я сталкивался с той же проблемой, много искал, и решением для меня была
createIndexes()
функция.Я хочу, чтобы это помогло.
так что код будет таким.
User = new Schema ({ email: {type: String, unique: true} }); User.createIndexes();
источник
Если вы используете такую опцию
autoIndex: false
в способе подключения:mongoose.connect(CONNECTION_STRING, { autoIndex: false });
Попробуйте удалить это. Если это не сработает, попробуйте перезапустить mongodb, как многие из них предлагают в этой теме.
источник
Вы можете определить свою схему как
User = new Schema ({ email: { type: String, unique: true } })
Но, возможно, это не сработает, если документ уже есть и после этого вы изменили схему пользователя. Вы можете создать индекс электронной почты для этой коллекции пользователей, если не хотите отбрасывать эту коллекцию. С помощью этой команды вы можете создать индекс электронной почты.
db.User.createIndex({email:1},{unique: true})
Или вы можете просто отбросить коллекцию и снова добавить пользователя.
Для удаления коллекции вы можете ввести это:
источник
Когда я столкнулся с этой проблемой, я попытался удалить базу данных, перезапустить сервер (nodemon) много раз, и ни один из приемов не работал вообще. Я нашел следующую работу через Robo 3T:
_id_
по умолчанию. Теперь выберите Добавить индексemail
для поля электронной почты, напримерПредоставьте ключи как JSON. Например
{ "email": 1 }
Установите флажок Уникальный
Это гарантирует, что в MongoDB не сохранятся повторяющиеся электронные письма.
источник
Убедитесь, что в вашей коллекции нет повторяющегося поля, в которое вы только что добавили уникальный индекс.
Затем просто перезапустите свое приложение (мангуст). Просто незаметно добавить индекс не удается.
источник
Удаление всех документов из коллекции:
И перезапуск, как упоминали другие, сработал для меня
источник
Если ваш MongoDB работает как служба (простой способ найти это, если вам не нужно подключаться к базе данных без запуска файла mongod.exe через терминал), то после внесения изменений вам может потребоваться перезапустить службу и / или полностью отказаться от базы данных.
Это довольно странно, потому что для некоторых пользователей работало просто удаление одной коллекции. Некоторым из них просто нужно было сбросить базу данных. Но у меня это не сработало. Я удалил базу данных, а затем перезапустил службу MongoDB Server.
Чтобы перезапустить службу поиска Службы на панели поиска Windows, затем найдите службу MongoDB, дважды щелкните, чтобы открыть, затем остановите и снова запустите службу.
Если другие методы не помогли вам, я считаю, что это сработает.
источник
В моем случае мангуст устарел. Я проверил это, запустив npm outdated на CMD. и обновил "мангуст".
Скажите, сработало ли это и для вас?
источник
Когда вы подключаете свою базу данных к приложению, добавьте эту опцию: «audoIndex: true», например, в моем коде я сделал это:
const options = { // your options go here ... // this code is the solution audoIndex: true } mongoose.connect(DB_URI, options);
Я также отбросил коллекцию, с которой у меня возникла проблема, и воссоздал ее, чтобы убедиться, что она будет работать. Я нашел это решение по адресу: https://dev.to/emmysteven/solved-mongoose-unique-index-not-working-45d5. Я также пробовал такие решения, как «перезапустить MongoDB», но у меня это не сработало.
источник