Mongodb Firavun Faresi E11000 Yinelenen Anahtar Hata Dizini


229

Aşağıdaki benim model userşema 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;

Bunu kontrol cihazımda kullanıyorum -

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

Ben böyle db kaydediyorum -

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"});
    }
});

Hata -

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

Ben db koleksiyon kontrol ve böyle bir yinelenen giriş yok, bana yanlış ne yaptığımı bildirin?

FYI - req.body.emailve req.body.passworddeğerler getiriliyor.

Ben de bu gönderiyi kontrol ettim ama yardım yok STACK LINK

Tamamen kaldırdıktan sonra belgeyi ekler, aksi takdirde local.email'de bir girişim olsa bile "Duplicate" hatası verir.


1
Aynı hata vardı! Geliştirme sırasında otomatik dizinlemeyi devre dışı bıraktık ve küçük şema adları / anahtarları kullanıyorduk. Daha sonra TitleCase'i kullanmaya karar verdik ancak dizin adlarımızı güncelleyemedik (yani: TitleCase yerine titleCase). Dizin oluşturmayı etkinleştirdiğimizde bu hatayı aldık. Anlamak için biraz zaman aldı. Tüm adların / anahtarların tam olarak her yerde adlandırıldığından emin olmak istersiniz.
Jeach

6
Aynı hatayla karşılaştım ve Firavun faresi modelinin unique: falseherhangi bir etkisi olmadı. Önce masayı bıraktığımı fark ettim ve sonra işe yarayacaktı. Gibi seomthing yapabilirsiniz db.whateverthecollection.drop({}). Dikkatli olun, koleksiyonu siler.
Pere

1
_id: mongoose.Types.ObjectId benzersiz kimlik gerektiği için ekleyin
Mayank Pandav

Yanıtlar:


241

Hata mesajı, nulle-posta olarak zaten bir kayıt olduğunu söylüyor . Başka bir deyişle, e-posta adresi olmayan bir kullanıcınız var.

Bununla ilgili belgeler:

Bir belgenin benzersiz bir dizindeki dizinlenmiş alan için bir değeri yoksa, dizin bu belge için boş bir değer depolar. Benzersiz kısıtlama nedeniyle, MongoDB yalnızca dizinlenmiş alanı olmayan bir belgeye izin verir. Dizinlenmiş alan için değeri olmayan birden çok belge varsa veya dizinlenmiş alan eksikse, dizin oluşturma yinelenen bir anahtar hatasıyla başarısız olur.

Bu boş değerleri benzersiz dizinden filtrelemek ve hatayı önlemek için benzersiz kısıtlamayı seyrek dizinle birleştirebilirsiniz.

benzersiz dizinler

Seyrek dizinler, dizin alanı boş değer içeriyor olsa bile, yalnızca dizinlenmiş alana sahip belgeler için girişler içerir.

Başka bir deyişle, birden fazla belgenin sahip olduğu bir seyrek dizin tamam null değerlere .

seyrek endeksler


Yorumlardan:

Sizin hata anahtarı adlandırılır söylüyor mydb.users.$email_1bana hem bir dizin var şüpheli yapar users.emailve users.local.email(eski ve şu anda kullanılmayan eski bir varlık). Mongoose modelinden bir alanın kaldırılması veritabanını etkilemez. mydb.users.getIndexes()Durumun bu olup olmadığını kontrol edin ve istenmeyen dizini ile manuel olarak kaldırın mydb.users.dropIndex(<name>).


1
Bu boş belgeyi kaldırdım ve işe yaradı :) +1 ..thx yardım için
Trialcoder

70
Sizin hata anahtarı adlandırılır söylüyor mydb.users.$email_1bana hem bir dizin var şüpheli yapar users.emailve users.local.email(eski ve şu anda kullanılmayan eski bir varlık). Mongoose modelinden bir alanın kaldırılması veritabanını etkilemez. mydb.users.getIndexes()Durumun bu olup olmadığını kontrol edin ve istenmeyen dizini ile manuel olarak kaldırın mydb.users.dropIndex(<name>).
RickN

17
Veya db.users.dropIndexes()birden çok dizin değişikliği yapıyorsanız kullanın
cs_stackX

1
Bu yeni kullanıcılar için bir kullanıcı adı ayarlamadan mongoose eklenti pasaport-yerel-mongoose kullanırken benim için bir sorundu.
sshow

1
Bu bir mesele ya da perspektif ya da hatta fikir, @titoih - null ya da bir değerin olmaması, tıpkı diğerleri gibi bir değer ya da özel bir durum mudur? "a @ bc" ve "a @ bc" aynı, "hiçbir şey" ve "hiçbir şey" de aynı mı? Seyrek olmayan bir indeksle cevap MongoDB'de "evet" dir. Diğer veritabanları (MySQL gibi) "hayır" der.
RickN

65

Hâlâ geliştirme ortamınızdaysanız, tüm db'yi bırakıp yeni şemanızla baştan başlarım.

Komut satırından

 mongo
use dbName;
db.dropDatabase();
exit

47
Bence bu çözüm çok agresif, db.collection.dropIndexes()cs_stackX'in söylediği gibi yeterli
JorgeGarza

2
@JorgeGarza Aynı sorunu yaşadım. Sadece koleksiyonu bıraktım ve bundan sonra her şey iyi çalışmaya başladı.
Sandip Subedi

Koleksiyonu iki alanım için benzersiz bir kimlikle yanlışlıkla başlattım. Daha sonra aynı kimliğe sahip birden fazla belge eklemek istediğimde, koleksiyonu silene ve yeniden işleme koyana kadar bana izin vermezdi.
Meir Snyder

1
Eğer gelişiminde yeni iseniz kullanıcı verilerinin gigabayt önceden saklanan sonra, bu sorunla bu ... ziyade çalıştırmak çözmek için nasıl iyi bir deneme şansı ve rakamdır
Janac Meena

@JorgeGarza'nın yorumu mantıklı. Sunucu yeniden başlatıldığında bırakılan dizinler bir kez daha Şema dosyası tarafından yeniden oluşturulur. Ayrıca işe yaradı.
retr0

26

Koleksiyon dizinlerini kontrol edin.

Farklı yeni yolla depolanması gereken alanlar için koleksiyondaki eski dizinler nedeniyle bu sorunu yaşadım.

Mongoose, alanı benzersiz olarak belirttiğinizde dizin ekler.


22

Temelde bu hata, örneğin "email_address" gibi belirli bir alanda benzersiz bir dizin bulunduğunu söylüyor, bu nedenle mongodb koleksiyondaki her belge için benzersiz e-posta adresi değeri bekliyor.

Diyelim ki, şemanızda daha önce benzersiz dizin tanımlanmadı ve daha sonra aynı e-posta adresine sahip veya e-posta adresi olmayan (boş değer) 2 kullanıcı kaydettiniz.

Daha sonra bir hata olduğunu gördünüz. böylece şemaya benzersiz bir dizin ekleyerek düzeltmeye çalışırsınız. Ancak koleksiyonunuzda zaten kopyalar var, bu nedenle hata mesajı tekrar tekrar bir değer ekleyemeyeceğinizi söylüyor.

Temel olarak üç seçeneğiniz vardır:

  1. Koleksiyonu bırak

    db.users.drop();

  2. Bu değere sahip belgeyi bulun ve silin. Diyelim ki değer null, bunu kullanarak silebilirsiniz:

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

  3. Benzersiz dizini bırakın:

    db.users.dropIndex(indexName)

Umarım bu yardımcı olmuştur :)


20

Bunun cevabını / çözümünü 5 yaşında bir çocuğa açıkladığım gibi açıklamak istiyorum, böylece herkes anlayabilir.

Bir uygulamam var.İnsanların e-postaları, şifreleri ve telefon numaralarıyla kaydolmalarını istiyorum. MongoDB veritabanımda, insanları hem telefon numaralarına hem de e-postalarına göre benzersiz bir şekilde tanımlamak istiyorum - bu, hem telefon numarasının hem de e-postanın her kişi için benzersiz olması gerektiği anlamına gelir.

Ancak, bir sorun var: Herkesin telefon numarasına sahip olduğunu, ancak herkesin e-posta adresine sahip olmadığını fark ettim.

E-posta adresi olmayanlar bana gelecek hafta e-posta adresi vereceğine söz verdiler. Ama yine de kayıtlı olmalarını istiyorum - bu yüzden telefon numaralarını e-posta-giriş alanını boş bıraktıkça kaydetmeye devam etmelerini söylüyorum.

Bunu yaparlar.

Veritabanım benzersiz bir e-posta adresi alanına İHTİYACI VAR - ancak e-posta adresi olarak 'null' olan birçok insanım var. Bu yüzden koduma gidiyorum ve veritabanı şemime, boş / null e-posta adresi alanlarına izin vermesini söylüyorum; bu, e-postalarını önümüzdeki hafta profillerine ekleyeceğine söz verdiğinde e-posta benzersiz adresleriyle dolduracağım.

Yani şimdi herkes için bir kazan-kazan (ama sen; -]): insanlar kayıt, ben onların verileri için mutluyum ... ve veritabanım mutlu çünkü güzel kullanılıyor ... ama ya sen? Henüz şemayı yapan kodu vermiyorum.

İşte kod: NOT: E-posta seyrek özelliği, daha sonra benzersiz değerlerle doldurulacak boş değerlere izin vermek için veritabanımı söyler.

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;

Umarım güzel açıklamışımdır. Mutlu NodeJS kodlama / hackleme!


bir sparsedizin ve uniquedoğrulama istiyorsanız ve zorunlu olmayan diğer alanlara sahipseniz partialFilterExpressionseçeneği kullanmanız gerekir . Bu yanıta bakın stackoverflow.com/a/34600171/728287
Gianfranco P.


4

Bu durumda, artık kullanmadığınız dizini bulmak için Mongo'ya giriş yapın (OP'nin 'e-postası' durumunda). Ardından Dizini Bırak'ı seçin resim açıklamasını buraya girin


3

Bu benim ilgili deneyimim:

'Kullanıcı' şemasında, 'isim' i benzersiz anahtar olarak ayarladım ve sonra veritabanı yapısını kurduğunu düşündüğüm bazı yürütmeler yaptım.

Ardından, benzersiz anahtarı 'kullanıcı adı' olarak değiştirdim ve verileri veritabanına kaydettiğimde artık 'ad' değerini geçmedim. Böylece mongodb, yeni kaydın 'name' değerini otomatik olarak yinelenen anahtar olan null olarak ayarlayabilir. Set 'name' anahtarını benzersiz anahtar olarak denedim {name: {unique: false, type: String}}Orijinal ayarı geçersiz kılmak için 'Kullanıcı' şemasında . Ancak, işe yaramadı.

Sonunda kendi çözümümü yaptım:

Veri kaydınızı kaydettiğinizde muhtemelen 'isim' anahtarına kopyalanmayacak rastgele bir anahtar değeri ayarlayın. Basitçe Matematik yöntemi '' + Math.random() + Math.random() rastgele bir dize yapar.


12
Bunun geçerli bir çözüm olduğunu düşünmüyorum, sadece sorunu maskeliyorsunuz.
Rick

Çirkin ama pragmatik
Anthony

3

Aynı sorunu yaşadım. Farklı şekillerde hata ayıklamayı denedim. Koleksiyonu bırakmayı denedim ve bundan sonra iyi çalıştı. Koleksiyonunuzda çok sayıda belge varsa bu iyi bir çözüm olmamasına rağmen. Ancak, gelişimin erken dönemindeyseniz, koleksiyonu düşürmeyi deneyin.

db.users.drop();

2

Çünkü zaten konfigürasyon ile aynı ada sahip bir koleksiyon var ... Sadece mongodb'dan mongo kabuğu aracılığıyla koleksiyonu kaldırın ve tekrar deneyin.

db.collectionName.remove ()

şimdi uygulamanızı çalıştırın


2

Benzer bir sorunum vardı ve varsayılan olarak mongo'nun koleksiyon başına sadece bir şemayı desteklediğini fark ettim. Yeni şemanızı farklı bir koleksiyonda saklayın veya mevcut koleksiyonunuzdaki uyumsuz şema ile mevcut belgeleri silin. Veya koleksiyon başına birden fazla şemaya sahip olmanın bir yolunu bulun.


2

Bu sorunla da karşılaştım ve çözdüm. Bu hata, e-postanın burada zaten mevcut olduğunu gösterir. Dolayısıyla, bu satırı e-posta özelliği için Modelinizden kaldırmanız yeterlidir.

unique: true

Bu, işe yaramasa bile mümkün olabilir. Bu yüzden koleksiyonu MongoDB'nizden silmeniz ve sunucunuzu yeniden başlatmanız yeterlidir.


1

Aynı sorunu, config / models.js dosyamda aşağıdaki yapılandırmaya sahipken de aldım

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

Göçü 'alter' den 'safe' olarak değiştirmek benim için düzeltti.

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

1

Bir şema gelen özelliklerini çıkardıktan sonra aynı sorun sonrailk kaydetme üzerine bazı dizinler oluşturduktan . şemadan özelliğin kaldırılması, hala bir dizini olan varolmayan bir özellik için boş bir değere yol açar. Dizini bırakmak veya sıfırdan yeni bir koleksiyonla başlamak burada yardımcı olur.

not: bu durumda hata mesajı sizi yönlendirecektir. artık var olmayan bir yolu var. im benim durumum eski yol ... $ uuid_1 (bu bir indeks!), ama yeni bir .... * priv.uuid_1


1

Mangoose kullanılarak tanımlanan şemayı değiştirmeye çalıştığımda da aynı sorunu yaşadım. Sorunun, kullanıcıdan gizlenen endeksleri (en azından benim durumumda) tanımlamak gibi bir koleksiyon oluştururken yapılan bazı temel işlemlerin sebebi olduğunu düşünüyorum. ve tekrar başlayın.


0

Ben de aynı sorunu yaşadım. Sorun, bir alanı modelden kaldırmamdı. Ne zaman db düştü giderir


0

gelecekteki geliştiriciler için, pusula kullanarak INDEX SEKMESİNDE dizini silmek öneririz ... Bu koleksiyonunuzdaki HERHANGİ BİR belge SİLMEYİN Dizinleri Yönet


-3

Veritabanında zaten varsa koleksiyon adını değiştirin, bir hata gösterecektir. Ve benzersiz olarak herhangi bir özellik verdiyseniz, aynı hata ortaya çıkar.


-4

Aynı sorun vardı uniqueözelliği öznitelik kaldırarak çözüldü .

Şemanız için benzersiz özellik değerlerini doğrulamanın veya kontrol etmenin başka bir yolunu bulmanız yeterlidir.


Çözümünüze bir örnek vermelisiniz.
Josh Adams

İlk olarak koleksiyonun temizlenmesi ve / veya tüm koleksiyonun mongo veritabanından silinmesi işe yaradı, ancak geçici bir çözümdü. Farklı kimliklere sahip olmalarına rağmen benzer değerlerle başka bir kayıt oluşturmak E11000 yinelenen anahtar hatası verdi. Ben sadece benzersiz öznitelik kaldırıldı bu özellik için yinelenen değerlere izin vermek istedim.
davyCode

-7

Lütfen koleksiyonu temizleyin veya tüm koleksiyonu MongoDB veritabanından silin ve daha sonra tekrar deneyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.