E11000 повторюваний індекс помилки ключових у мангустів


228

Далі йде моя userсхема в user.jsмоделі -

var userSchema = new mongoose.Schema({
    local: {
        name: { type: String },
        email : { type: String, require: true, unique: true },
        password: { type: String, require:true },
    },
    facebook: {
        id           : { type: String },
        token        : { type: String },
        email        : { type: String },
        name         : { type: String }
    }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

Ось як я його використовую в своєму контролері -

var user = require('./../models/user.js');

Ось як я зберігаю його в db -

user({'local.email' : req.body.email, 'local.password' : req.body.password}).save(function(err, result){
    if(err)
        res.send(err);
    else {
        console.log(result);
        req.session.user = result;
        res.send({"code":200,"message":"Record inserted successfully"});
    }
});

Помилка -

{"name":"MongoError","code":11000,"err":"insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.users.$email_1  dup key: { : null }"} 

Я перевірив колекцію db і не існує такої копії запису, дайте мені знати, що я роблю неправильно?

FYI - req.body.emailі req.body.passwordотримують значення.

Я також перевірив цю посаду, але ніякої допомоги СТАЙТЕ ЛІНКУ

Якщо я видалив повністю, то він вставляє документ, інакше він видає помилку "Копіювати" помилку, навіть у мене є запис у local.email


1
Була така ж помилка! Під час розробки ми відключили автоматичну індексацію та використовували малі імена / ключі схеми. Пізніше ми вирішили використати TitleCase замість цього, але не вдалось оновити наші індексні імена (тобто: titleCase замість TitleCase). Тож коли ми включили індексацію, ми отримали цю помилку. Потрібно трохи розібратися. Ви хочете переконатися, що всі імена / ключі названі точно скрізь.
Jeach

6
У мене була така ж помилка, і налаштування мангустової моделі unique: falseне мала жодного впливу. Я зрозумів, що спочатку я повинен кинути стіл, а потім це спрацює. Можна робити подібні речі db.whateverthecollection.drop({}). Будьте уважні, він видаляє колекцію.
Пере

1
_id: mongoose.Types.ObjectId додати, оскільки потрібен унікальний ідентифікатор
Mayank Pandav

Відповіді:


239

Повідомлення про помилку говорить про те, що вже є запис із nullелектронною поштою. Іншими словами, у вас вже є користувач без електронної адреси.

Відповідна документація для цього:

Якщо документ не має значення для індексованого поля в унікальному індексі, індекс буде зберігати нульове значення для цього документа. Через унікальне обмеження MongoDB дозволить лише один документ, у якому відсутнє індексоване поле. Якщо існує більше одного документа без значення для індексованого поля або відсутнє індексоване поле, збірка індексу не вдасться із помилкою повторюваного ключа.

Ви можете комбінувати унікальне обмеження з розрідженим індексом, щоб відфільтрувати ці нульові значення з унікального індексу та уникнути помилки.

унікальні індекси

Рідкі індекси містять записи лише для документів, які мають індексоване поле, навіть якщо поле індексу містить нульове значення.

Іншими словами, розріджений індекс нормальний, у кількох документах всі nullзначення.

розріджені показники


З коментарів:

Ваша помилка говорить про те, що названий ключ, mydb.users.$email_1який змушує мене підозрювати, що у вас є індекс users.emailі на users.local.email(і на попередній момент, він не використовується) Видалення поля з моделі Mongoose не впливає на базу даних. Перевірте, mydb.users.getIndexes()чи це так, і видаліть небажаний індекс вручну mydb.users.dropIndex(<name>).


1
Я щойно видалив цей нульовий документ, і він працював :) +1 ..thx для допомоги
Trialcoder

70
Ваша помилка говорить про те, що названий ключ, mydb.users.$email_1який змушує мене підозрювати, що у вас є індекс users.emailі на users.local.email(і на попередній момент, він не використовується) Видалення поля з моделі Mongoose не впливає на базу даних. Перевірте, mydb.users.getIndexes()чи це так, і видаліть небажаний індекс вручну mydb.users.dropIndex(<name>).
RickN

17
Або скористайтеся, db.users.dropIndexes()якщо ви
вносите

1
Це було проблемою для мене, коли я використовував монгозний плагін-паспорт-локальний-мангуст, не встановлюючи ім’я користувача для нових користувачів.
sshow

1
Це питання або перспектива або, можливо, навіть думка, @titoih - це недійсне значення або відсутність значення, як і будь-яке інше, або це особливий випадок? "a @ bc" і "a @ bc" однакові, чи "нічого" і "нічого" також не відрізняються? З нестримним індексом відповідь "Так" у MongoDB. Інші бази даних (наприклад, MySQL) скажуть «ні».
RickN

64

Якщо ви все ще знаходитесь у вашому середовищі розробки, я би скинув весь db і почав би все з вашої нової схеми.

З командного рядка

 mongo
use dbName;
db.dropDatabase();
exit

46
Я думаю, що це рішення є дуже агресивним, я думаю, що цього достатньо, db.collection.dropIndexes()як сказав
cs_stackX

2
@JorgeGarza У мене виникло те саме питання. Я просто скинув колекцію і все почало нормально працювати після цього.
Сандіп Субєді

Я випадково ініціалізував колекцію з унікальним Id для двох моїх полів. Пізніше, коли я хотів додати декілька документів з тим самим ідентифікатором, він не дозволив мені, поки я не видалив колекцію та не отримав її знову.
Меїр Снайдер

1
Якщо ви новачок у своїй розробці, це хороший шанс поекспериментувати і розібратися, як вирішити це питання, а не запускати цю проблему, коли у вас вже будуть збережені гігабайти даних користувачів
Janac Meena

Коментар @JorgeGarza має сенс. Відкинуті індекси будуть відновлені ще раз файлом схеми при перезапуску сервера. Також це спрацювало.
retr0

26

Перевірте індекси колекції.

У мене виникла ця проблема через застарілі індекси в колекції для полів, які слід зберігати іншим новим шляхом.

Мангуст додає індекс, коли ви вказуєте поле як унікальне.


21

В основному ця помилка говорить про те, що у вас був унікальний індекс для певного поля, наприклад: "email_address", тому mongodb очікує унікального значення адреси електронної пошти для кожного документа в колекції.

Скажімо, раніше у вашій схемі унікальний індекс не визначався, і тоді ви зареєструвались 2 користувачі з однаковою електронною адресою або без електронної адреси (нульове значення).

Пізніше ви побачили, що сталася помилка. тому ви намагаєтеся виправити це, додавши в схему унікальний індекс. Але у вашій колекції вже є дублікати, тому повідомлення про помилку говорить про те, що ви не можете знову вставити повторюване значення.

У вас є три варіанти:

  1. Видаліть колекцію

    db.users.drop();

  2. Знайдіть документ, який має це значення, і видаліть його. Скажімо, значення було недійсним, його можна видалити за допомогою:

    db.users.remove({ email_address: null });

  3. Відкиньте унікальний індекс:

    db.users.dropIndex(indexName)

Сподіваюся, це допомогло :)


18

Я хочу пояснити відповідь / рішення на це так, як я пояснюю 5-річному, тому кожен може зрозуміти.

У мене є додаток. Я хочу, щоб люди зареєструвалися за допомогою своєї електронної пошти, пароля та номера телефону. У своїй базі даних MongoDB я хочу ідентифікувати людей унікально на основі їхніх номерів телефонів та електронної пошти - тому це означає, що і номер телефону, і електронна адреса повинні бути унікальними для кожної людини.

Однак є проблема: я зрозумів, що кожен має номер телефону, але не кожен має адресу електронної пошти.

Ті, у кого немає електронної адреси, пообіцяли мені, що вони отримають електронну адресу до наступного тижня. Але я хочу, щоб вони все-таки були зареєстровані - тому я кажу їм продовжити реєстрацію своїх телефонних номерів, коли вони залишають поле введення електронної пошти порожнім.

Вони так і роблять.

Моя база даних ПОТРЕБАЄ унікальне поле електронної адреси - але у мене дуже багато людей, які мають "null" як свою адресу електронної пошти. Тож я переходжу до свого коду і кажу своїй схемі бази даних, щоб дозволити порожні / нульові адреси електронної пошти, які згодом я заповнять унікальними адресами електронної пошти, коли люди, які пообіцяли додати свої електронні листи до своїх профілів, наступного тижня.

Тож це вже виграшна вигода для всіх (але ви; -]): люди реєструються, я радий мати їхні дані ... і моя база даних щаслива, тому що вона прекрасно використовується ... але що з вами? Я ще маю дати вам код, який створив схему.

Ось код: ПРИМІТКА: Рідке властивість в електронній пошті - це те, що вказує моїй базі даних дозволяти нульові значення, які згодом будуть заповнені унікальними значеннями.

var userSchema = new mongoose.Schema({
  local: {
    name: { type: String },
    email : { type: String, require: true, index:true, unique:true,sparse:true},
    password: { type: String, require:true },
  },
  facebook: {
    id           : { type: String },
    token        : { type: String },
    email        : { type: String },
    name         : { type: String }
  }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

Я сподіваюся, що я це добре пояснив. Щасливе кодування / злому NodeJS!


якщо ви хочете, щоб sparseіндекс і uniqueвалідація мали інші поля, які не обов'язкові, вам потрібно буде скористатися цією partialFilterExpressionопцією. Дивіться цю відповідь stackoverflow.com/a/34600171/728287
Gianfranco P.


4

У цій ситуації увійдіть до Mongo, щоб знайти індекс, яким ви більше не користуєтесь (у випадку OP '' email '). Потім виберіть « Drop Index» введіть тут опис зображення


3

Це мій досвід відновлення:

У схемі "Користувач" я встановив "ім'я" як унікальний ключ, а потім запустив деяке виконання, яке, на мою думку, створило структуру бази даних.

Потім я змінив унікальний ключ на "ім'я користувача", і більше не передав значення "ім'я", коли я зберігав дані в базі даних. Таким чином, mongodb може автоматично встановити значення "name" нової записи як null, що є дублікатом ключа. Я спробував встановити клавішу 'name' як не унікальний ключ {name: {unique: false, type: String}}у схемі 'User', щоб змінити оригінальний параметр. Однак не вийшло.

Нарешті я прийняв власне рішення:

Просто встановіть випадкове значення ключа, яке, швидше за все, не буде повторюваним ключем 'name', коли ви зберігаєте запис даних. Просто метод Math '' + Math.random() + Math.random() робить випадкову рядок.


12
Я не думаю, що це правильне рішення, ви просто маскуєте проблему.
Рік

Потворний, але прагматичний
Ентоні

3

У мене було те саме питання. Спробували налагодження різних способів не вдалося з'ясувати. Я спробував скинути колекцію, і вона спрацювала нормально після цього. Хоча це не гарне рішення, якщо у вашій колекції багато документів. Але якщо ви перебуваєте в ранньому стані розвитку, спробуйте скинути колекцію.

db.users.drop();

2

Це тому, що вже є колекція з такою ж назвою з конфігурацією. Просто вийміть колекцію зі свого mongodb через оболонку mongo та спробуйте ще раз.

db.collectionName.remove ()

тепер запустіть свою програму, вона повинна працювати


2

У мене була подібна проблема, і я зрозумів, що mongo за замовчуванням підтримує лише одну схему на колекцію. Або зберігайте свою нову схему в іншій колекції або видаляйте існуючі документи з несумісною схемою в поточній колекції. Або знайти спосіб мати більше однієї схеми на колекцію.


2

Я також зіткнувся з цим питанням і вирішив його. Ця помилка показує, що електронний лист тут уже присутній. Тому вам просто потрібно видалити цей рядок із атрибута Модель для електронної пошти.

unique: true

Це можливо, навіть якщо це не спрацює. Тому просто потрібно видалити колекцію зі свого MongoDB та перезапустити сервер.


1

Цю проблему я отримав, коли в конфігурації / models.js у мене була така конфігурація

module.exports.models = {
  connection: 'mongodb',
  migrate: 'alter'
}

Зміна міграції з "alter" на "safe" виправила це для мене.

module.exports.models = {
  connection: 'mongodb',
  migrate: 'safe'
}

1

той самий випуск після видалення властивостей із схеми після першого побудови деяких індексів щодо збереження. видалення властивості зі схеми призводить до нульового значення для неіснуючого властивості, яке все ще мало індекс. тут допомагає випадання індексу або початок з нової колекції з нуля.

Примітка: повідомлення про помилку призведе вас до цього випадку. у неї є шлях, якого вже не існує. в моєму випадку старий шлях був ... $ uuid_1 (це індекс!), але новий ... * priv.uuid_1


1

У мене була така ж проблема, коли я намагався змінити схему, визначену за допомогою мангусти. Я думаю, що проблема пов'язана з тією причиною, що під час створення колекції робиться якийсь основоположний процес, як опис індексів, які приховані від користувача (принаймні в моєму випадку). Тож найкращим рішенням, яке я знайшов, було залишити всю колекцію і почніть знову.


0

У мене був той самий випуск. Проблема полягала в тому, що я видалив одне поле з моделі. Коли я скинув db, він виправляється



-3

Змініть ім'я колекції, якщо воно вже існує в базі даних, воно покаже помилку. І якщо ви надали якесь властивість як унікальне, відбудеться та сама помилка.


-4

Якщо було те саме питання, я вирішив її, видаливши uniqueатрибут у властивості.

Просто знайдіть інший спосіб перевірити або перевірити наявність унікальних значень властивості для вашої схеми.


Наведіть приклад свого рішення.
Джош Адамс

Перше очищення колекції та / або видалення всієї колекції з бази даних mongo, але це було тимчасовим рішенням. Створення ще однієї записи з подібними значеннями, хоча вони мали різні ідентифікатори, все-таки давали помилку дублювання ключа E11000. Я хотів дозволити повторювані значення для цього властивості, тому я просто видалив унікальний атрибут.
davyCode

-7

Очистіть колекцію або видаліть всю колекцію з бази даних MongoDB і повторіть спробу пізніше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.