E11000 indeks kesalahan kunci duplikat di mongodb luwak

229

Berikut ini adalah userskema saya dalam user.jsmodel -

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;

Ini adalah bagaimana saya menggunakannya di controller saya -

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

Ini adalah bagaimana saya menyimpannya di 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"});
    }
});

Kesalahan -

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

Saya memeriksa koleksi db dan tidak ada entri duplikat seperti itu, beri tahu saya apa yang saya lakukan salah?

FYI - req.body.emaildan req.body.passwordsedang mengambil nilai.

Saya juga memeriksa posting ini tetapi tidak ada bantuan STACK LINK

Jika saya dihapus sepenuhnya maka akan menyisipkan dokumen, jika tidak maka akan terjadi kesalahan "Duplikat" bahkan saya memiliki entri di local.email

Trialcoder
sumber
1
Mengalami kesalahan yang sama! Selama pengembangan, kami menonaktifkan pengindeksan otomatis dan menggunakan nama / kunci skema huruf kecil. Kami kemudian memutuskan untuk menggunakan TitleCase sebagai gantinya tetapi gagal memperbarui nama indeks kami (yaitu: titleCase alih-alih TitleCase). Jadi ketika kami mengaktifkan pengindeksan, kami mendapatkan kesalahan ini. Butuh beberapa saat untuk mengetahuinya. Anda ingin memastikan semua nama / kunci diberi nama persis di mana saja.
Jeach
6
Saya memiliki kesalahan yang sama dan pengaturan model luwak unique: falsetidak memiliki dampak apa pun. Saya menyadari bahwa saya harus pertama-tama menjatuhkan meja dan kemudian berhasil. Anda bisa melakukan hal seperti itu db.whateverthecollection.drop({}). Hati-hati, itu menghapus koleksi.
Pere
1
_id: mongoose.Types.ObjectId tambahkan karena id unik diperlukan
Mayank Pandav

Jawaban:

241

Pesan kesalahan mengatakan bahwa sudah ada catatan dengan nullsebagai email. Dengan kata lain, Anda sudah memiliki pengguna tanpa alamat email.

Dokumentasi yang relevan untuk ini:

Jika dokumen tidak memiliki nilai untuk bidang yang diindeks dalam indeks unik, indeks akan menyimpan nilai nol untuk dokumen ini. Karena kendala unik, MongoDB hanya akan mengizinkan satu dokumen yang tidak memiliki bidang yang diindeks. Jika ada lebih dari satu dokumen tanpa nilai untuk bidang yang diindeks atau tidak ada bidang yang diindeks, pembuatan indeks akan gagal dengan kesalahan kunci duplikat.

Anda bisa menggabungkan batasan unik dengan indeks jarang untuk menyaring nilai-nilai nol ini dari indeks unik dan menghindari kesalahan.

indeks unik

Indeks jarang hanya berisi entri untuk dokumen yang memiliki bidang yang diindeks, bahkan jika bidang indeks berisi nilai nol.

Dengan kata lain, indeks jarang ok dengan beberapa dokumen semua memiliki nullnilai.

indeks jarang


Dari komentar:

Kesalahan Anda mengatakan bahwa kunci tersebut dinamai mydb.users.$email_1yang membuat saya curiga bahwa Anda memiliki indeks pada keduanya users.emaildan users.local.email(Yang lama dan tidak digunakan saat ini). Menghapus bidang dari model luwak tidak memengaruhi basis data. Periksa mydb.users.getIndexes()apakah ini masalahnya dan secara manual hapus indeks yang tidak diinginkan mydb.users.dropIndex(<name>).

RickN
sumber
1
Saya baru saja menghapus dokumen nol itu dan berhasil :) +1 .. thx untuk bantuan
Trialcoder
70
Kesalahan Anda mengatakan bahwa kunci tersebut dinamai mydb.users.$email_1yang membuat saya curiga bahwa Anda memiliki indeks pada keduanya users.emaildan users.local.email(Yang lama dan tidak digunakan saat ini). Menghapus bidang dari model luwak tidak memengaruhi basis data. Periksa mydb.users.getIndexes()apakah ini masalahnya dan secara manual hapus indeks yang tidak diinginkan mydb.users.dropIndex(<name>).
RickN
17
Atau gunakan db.users.dropIndexes()jika Anda membuat banyak perubahan indeks
cs_stackX
1
Ini merupakan masalah bagi saya ketika saya menggunakan plugin luwak-paspor-lokal-luwak tanpa menetapkan nama pengguna untuk pengguna baru.
sshow
1
Ini masalah atau perspektif atau bahkan opini, @titoih - apakah nol atau tidak adanya nilai sama seperti yang lain atau apakah ini merupakan kasus khusus? "a @ bc" dan "a @ bc" sama, apakah "tidak ada" dan "tidak ada" yang sama? Dengan indeks non-sparse jawabannya adalah "ya" di MongoDB. Database lain (seperti MySQL) akan mengatakan "tidak".
RickN
65

Jika Anda masih dalam lingkungan pengembangan Anda, saya akan menjatuhkan seluruh db dan memulai kembali dengan skema baru Anda.

Dari baris perintah

 mongo
use dbName;
db.dropDatabase();
exit
Rick
sumber
47
Saya pikir solusi ini sangat agresif, saya pikir sudah cukup dengan db.collection.dropIndexes()seperti kata
cs_stackX
2
@ JorgeGarza Saya punya masalah yang sama. Saya baru saja menjatuhkan koleksi dan semuanya mulai berfungsi dengan baik setelah itu.
Sandip Subedi
Saya tidak sengaja menginisialisasi koleksi dengan Id unik untuk dua bidang saya. Kemudian ketika saya ingin menambahkan beberapa dokumen dengan ID yang sama, itu tidak akan membiarkan saya sampai saya menghapus koleksi dan memprosesnya kembali.
Meir Snyder
1
Jika Anda baru dalam pengembangan Anda, ini adalah kesempatan yang baik untuk bereksperimen dan mencari cara mengatasi ini ... daripada mengalami masalah ini setelah Anda memiliki gigabytes data pengguna yang sudah disimpan
Janac Meena
Komentar @JorgeGarza masuk akal. Indeks yang hilang akan dibangun kembali oleh file Schema saat server dihidupkan ulang. Juga, itu berhasil.
Retret
26

Periksa indeks koleksi.

Saya punya masalah itu karena indeks yang sudah ketinggalan zaman dalam koleksi untuk bidang, yang harus disimpan oleh jalur baru yang berbeda.

Mongoose menambahkan indeks, saat Anda menentukan bidang sebagai unik.

Yegor
sumber
22

Yah pada dasarnya kesalahan ini mengatakan, bahwa Anda memiliki indeks unik pada bidang tertentu misalnya: "email_address", jadi mongodb mengharapkan nilai alamat email unik untuk setiap dokumen dalam koleksi.

Jadi katakanlah, sebelumnya dalam skema Anda indeks unik tidak ditentukan, dan kemudian Anda mendaftar 2 pengguna dengan alamat email yang sama atau tanpa alamat email (nilai nol).

Kemudian, Anda melihat ada kesalahan. jadi Anda mencoba memperbaikinya dengan menambahkan indeks unik ke skema. Tetapi koleksi Anda sudah memiliki duplikat, jadi pesan kesalahan mengatakan bahwa Anda tidak dapat memasukkan nilai duplikat lagi.

Anda pada dasarnya memiliki tiga opsi:

  1. Jatuhkan koleksi

    db.users.drop();

  2. Temukan dokumen yang memiliki nilai itu dan hapus. Katakanlah nilainya nol, Anda dapat menghapusnya menggunakan:

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

  3. Jatuhkan indeks Unik:

    db.users.dropIndex(indexName)

Semoga ini membantu :)

Daksh Miglani
sumber
20

Saya ingin menjelaskan jawaban / solusi untuk ini seperti saya menjelaskan kepada anak berusia 5 tahun, sehingga semua orang bisa mengerti.

Saya punya aplikasi. Saya ingin orang mendaftar dengan email, kata sandi, dan nomor telepon mereka. Dalam database MongoDB saya, saya ingin mengidentifikasi orang secara unik berdasarkan nomor telepon dan email mereka - jadi ini berarti bahwa nomor telepon dan email harus unik untuk setiap orang.

Namun, ada masalah: Saya telah menyadari bahwa setiap orang memiliki nomor telepon tetapi tidak semua orang memiliki alamat email.

Mereka yang tidak memiliki alamat email telah berjanji kepada saya bahwa mereka akan memiliki alamat email minggu depan. Tetapi saya tetap ingin agar mereka terdaftar - jadi saya memberi tahu mereka untuk melanjutkan mendaftarkan nomor telepon mereka ketika mereka membiarkan bidang input-email kosong.

Mereka melakukannya.

Basis data saya MEMBUTUHKAN bidang alamat email yang unik - tetapi saya memiliki banyak orang dengan 'nol' sebagai alamat email mereka. Jadi saya pergi ke kode saya dan memberitahu skema database saya untuk mengizinkan bidang alamat email kosong / nol yang nantinya akan saya isi dengan alamat email unik ketika orang-orang yang berjanji untuk menambahkan email mereka ke profil mereka minggu depan.

Jadi sekarang ini adalah win-win untuk semua orang (tetapi Anda; -]): orang-orang mendaftar, saya senang memiliki data mereka ... dan database saya senang karena digunakan dengan baik ... tetapi bagaimana dengan Anda? Saya belum memberi Anda kode yang membuat skema.

Berikut adalah kodenya: CATATAN: Properti jarang dalam email, adalah yang memberitahu basis data saya untuk memungkinkan nilai nol yang nantinya akan diisi dengan nilai unik.

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;

Saya harap saya telah menjelaskannya dengan baik. Selamat NodeJS coding / peretasan!

Daggie Blanqx - Douglas Mwangi
sumber
jika Anda menginginkan sparseindeks dan uniquevalidasi, dan memiliki bidang lain yang tidak diperlukan, Anda harus menggunakan partialFilterExpressionopsi. Lihat jawaban ini stackoverflow.com/a/34600171/728287
Gianfranco P.
4

Dalam situasi ini, masuk ke Mongo menemukan indeks yang tidak Anda gunakan lagi (dalam kasus OP 'email'). Kemudian pilih Drop Index masukkan deskripsi gambar di sini

papan bumsover
sumber
3

Ini pengalaman saya yang relavan:

Dalam skema 'Pengguna', saya menetapkan 'nama' sebagai kunci unik dan kemudian menjalankan beberapa eksekusi, yang saya pikir telah mengatur struktur basis data.

Kemudian saya mengubah kunci unik sebagai 'nama pengguna', dan tidak lagi meneruskan nilai 'nama' ketika saya menyimpan data ke basis data. Jadi mongodb dapat secara otomatis menetapkan nilai 'nama' dari catatan baru sebagai null yang merupakan kunci duplikat. Saya mencoba menetapkan kunci 'nama' sebagai bukan kunci unik {name: {unique: false, type: String}}dalam skema 'Pengguna' untuk mengganti pengaturan asli. Namun, itu tidak berhasil.

Akhirnya, saya membuat solusi sendiri:

Cukup tetapkan nilai kunci acak yang tidak akan mungkin menjadi duplikat untuk kunci 'nama' saat Anda menyimpan catatan data Anda. Metode sederhana Matematika '' + Math.random() + Math.random() membuat string acak.

Kobe Luo
sumber
12
Saya tidak berpikir ini adalah solusi yang valid, Anda hanya menutupi masalahnya.
Rick
Jelek tapi pragmatis
Anthony
3

Saya memiliki masalah yang sama. Mencoba men-debug cara yang berbeda tidak dapat menemukannya. Saya mencoba menjatuhkan koleksinya dan berhasil setelah itu. Meskipun ini bukan solusi yang baik jika koleksi Anda memiliki banyak dokumen. Tetapi jika Anda berada dalam tahap awal pengembangan, coba jatuhkan koleksinya.

db.users.drop();
Sandip Subedi
sumber
2

Ini karena sudah ada koleksi dengan nama yang sama dengan konfigurasi .. Cukup hapus koleksi dari mongodb Anda melalui mongo shell dan coba lagi.

db.collectionName.remove ()

sekarang jalankan aplikasi Anda itu harus berfungsi

Ignatius Andrew
sumber
2

Saya memiliki masalah yang sama dan saya menyadari bahwa secara default mongo hanya mendukung satu skema per koleksi. Simpan skema baru Anda di koleksi yang berbeda atau hapus dokumen yang ada dengan skema yang tidak kompatibel dalam koleksi Anda saat ini. Atau temukan cara untuk memiliki lebih dari satu skema per koleksi.

Embedded_Mugs
sumber
2

Saya juga menghadapi masalah ini dan saya menyelesaikannya. Kesalahan ini menunjukkan bahwa email sudah ada di sini. Jadi, Anda hanya perlu menghapus baris ini dari atribut Model untuk email Anda.

unique: true

Ini mungkin terjadi bahkan jika itu tidak akan berhasil. Jadi hanya perlu menghapus koleksi dari MongoDB Anda dan restart server Anda.

Inamur Rahman
sumber
1

Saya mendapatkan masalah yang sama ketika saya memiliki konfigurasi berikut di config / models.js saya

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

Mengubah migrasi dari 'ubah' ke 'aman' memperbaikinya untuk saya.

module.exports.models = {
  connection: 'mongodb',
  migrate: 'safe'
}
Jam Risser
sumber
1

masalah yang sama setelah menghapus properti dari skema setelah terlebih dahulu membangun beberapa indeks pada tabungan. menghapus properti dari skema mengarah ke nilai nol untuk properti yang tidak ada, yang masih memiliki indeks. menjatuhkan indeks atau memulai dengan koleksi baru dari awal membantu di sini.

Catatan: pesan kesalahan akan menuntun Anda dalam kasus itu. ia memiliki jalan, yang tidak ada lagi. im kasus saya jalur lama adalah ... $ uuid_1 (ini adalah indeks!), tetapi yang baru adalah .... * priv.uuid_1

chhtm
sumber
1

Saya memiliki masalah yang sama ketika saya mencoba untuk memodifikasi skema yang didefinisikan menggunakan mangga. Saya pikir masalah ini disebabkan oleh alasan bahwa ada beberapa proses mendasar yang dilakukan ketika membuat koleksi seperti menggambarkan indeks yang disembunyikan dari pengguna (setidaknya dalam kasus saya). Jadi solusi terbaik yang saya temukan adalah dengan menghapus seluruh koleksi dan mulai lagi.

Rahul P
sumber
0

Saya memiliki masalah yang sama. Masalahnya adalah bahwa saya telah menghapus satu bidang dari model. Ketika saya menjatuhkan db itu diperbaiki

pengguna86168
sumber
0

untuk pengembang masa depan, saya sarankan, hapus indeks di TAB INDEKS menggunakan kompas ... ini BUKAN HAPUS dokumen apa pun dalam koleksi Anda Kelola Indeks

Edgar Olivar
sumber
-3

Ubah nama koleksi jika sudah ada dalam database, itu akan menampilkan kesalahan. Dan jika Anda memberikan properti apa pun sebagai unik kesalahan yang sama akan terjadi.

arul mb
sumber
-4

Punya masalah yang sama saya mengatasinya dengan menghapus uniqueatribut di properti.

Temukan saja cara lain untuk memvalidasi atau memeriksa nilai properti unik untuk skema Anda.

davyCode
sumber
Anda harus memberikan contoh dengan solusi Anda.
Josh Adams
Pertama membersihkan koleksi dan / atau menghapus seluruh koleksi dari database mongo berhasil, itu adalah solusi sementara. Membuat catatan lain dengan nilai yang sama meskipun mereka memiliki id yang berbeda masih memberikan kesalahan kunci duplikat E11000. Saya ingin mengizinkan nilai duplikat untuk properti itu jadi saya cukup menghapus atribut unik.
davyCode
-7

Harap hapus koleksi atau Hapus seluruh koleksi dari database MongoDB dan coba lagi nanti.

Vittal Kamkar
sumber