2016-03-23 16 views
1

MongoDb/Mongoose için oldukça yeni, SQL Server veya Oracle için daha çok kullanıyorum.Mongoose'da yinelenen kayıtları önleme

Etkinlik için oldukça basit bir şema sahibiyim. Bunu yapmanın iki yolu gösterir Mongoose Indexes bakıyordu

EventSchema.add({ 
    pkey: { type: String, unique: true }, 
    device: { type: String, required: true }, 
    name: { type: String, required: true }, 
    owner: { type: String, required: true }, 
    description: { type: String, required: true }, 
}); 

, ben saha tanımını kullandı.

Ayrıca, bir POST kabul eden ve bu koleksiyonda kayıt eklemek için çağırılan çok basit bir API'ye sahibim.

Aynı pkeyle bir kaydın ekinin gerçekleşmemesi gerektiğini ve benzersiz olanın çalıştığını kontrol eden bir test yazdım: true çalışıyor. Zaten bir dizi okuduğum bir dizi olayım var, bu yüzden sadece bu olayların birincisini POST ve ne olduğunu görüyorum, mongo DB'nin E11000 yinelenen anahtar hatasını atmasını bekledim, fakat bu olmadı.

var url = 'api/events'; 
var evt = JSON.parse(JSON.stringify(events[0])); 

// POST'ed new record won't have an _id yet 
delete evt._id; 

api.post(url) 
    .send(evt) 
    .end(err, res) { 
    err.should.exist; 
    err.code.should.equal(11000); 
    }); 

Test başarısız oluyor, hata yok ve çift kayıt ekleniyor.

Koleksiyona baktığımda, her ikisinin de aynı pkeyle (orijinal kaydı ve sınama için gönderdiğim kopya) iki kayıt görebiliyorum. İkinci kaydın, ilk ancak daha sonra değiştirilmiş bir tarihle aynı oluşturma tarihine sahip olduğunu fark ettim.

(Mongo son değiştirilmiş versiyonu rekoru ??? kullanmak için bana bekler, URL farklıysa ve böylece kimliğidir) O eşsiz kabul vardı

[ { _id: 2, 
    pkey: '6fea271282eb01467020ce70b5775319', 
    name: 'Event name 01', 
    owner: 'Test Owner', 
    device: 'Device X', 
    description: 'I have no idea what\'s happening', 
    __v: 0, 
    url: '/api/events/2', 
    modified: '2016-03-23T07:31:18.529Z', 
    created: '2016-03-23T07:31:18.470Z' }, 
    { _id: 1, 
    pkey: '6fea271282eb01467020ce70b5775319', 
    name: 'Event name 01', 
    owner: 'Test Owner', 
    device: 'Device X', 
    description: 'I have no idea what\'s happening', 
    __v: 0, 
    url: '/api/events/1', 
    modified: '2016-03-23T07:31:18.470Z', 
    created: '2016-03-23T07:31:18.470Z' } 
] 

: alanına tanımına gerçek mongo anlattı db istediğin şeyi ve mongo bunu senin için kurtardı, ya da belki bir şeyi yanlış anladım ...

SQL terimlerinde, URL aramasında kullanılabilecek bir anahtar oluşturursunuz, ancak benzersiz bir bileşik indeksi oluşturabilirsiniz. Yinelenen ekler önlemek için. Bir olaydaki hangi alanların rekoru benzersiz hale getirdiğini tanımlayabilmem gerekir çünkü bir form vericisi POST bir formun göndericisinin bir sonraki kullanılabilir _id değerine sahip değildir, ancak _id ("mongoose-auto-increment") ile yapılır uygulamanın diğer bölgelerinden gelen URL kullanımı

/events/Event%20name%2001%5fDevice%20X%5fTest%20Owner 

gibi

/events/1 

değil bileşik değerlerinin tam bir karmaşa gibi temiz olmasını sağlamak amacıyla) Ben kodlama başlamak üzereydim Şimdilik sadece bu tek dizgeye karşı basit bir test yazdım, ama gerçek şemanın birkaç tane alanı var ve bunların bir arada kullanılmasını tek başıma kullanacağım, gerçekten ilk teste ulaşmak istiyorum. Daha fazla test, daha fazla alan ve daha fazla kod eklemeye başlamadan önce çalışıyorum.

İkinci kaydın gerçekten eklenmediğinden emin olmak için yapmam gereken bir şey var mı?

+0

Muhtemelen biraz okuma yapmalı ve "madatory" '_id' alanının aslında birincil anahtar olduğunu fark etmiş olmalısınız. Burada bir şey yapmış olmanız gerekir çünkü orada sayısal değerler bulunmaz (varsayılan sayısal anahtar). Ve eğer gerçekten "benzersiz bir birincil anahtar" olan başka bir değeriniz varsa, bunu yerine '_id' içine koymalısınız. Küçük bir okuma, çok fazla sorun yaratacaktır. –

+1

Bazı şeyleri okuyun, bu yararlı değil ..., görünüşe göre _id oluşturur ve her kaydetme 1 yukarı çıkmasını sağlar "mongoose-auto-increment" dahil. _id/events /: id için benzersiz ve kullanışlı olabilir, ancak bu rekoru benzersiz kılan şey değildir, bu olaydan alanların bileşik bir kombinasyonu ile belirlenir (eklenecek). Dizine birden fazla değer eklemeye ve tüm şeyi kodlamaya başlamadan önce şemanın bir alanında daha basit bir testle çalışıp çalışmayacağını görmek istedim. Bir bileşik anahtar değeri, –

cevap

0

eklenti:

o endeksi ikinci uç yayınlanmıştır önce (benim test paketi aralarındaki tek 9ms orada gibi) güncellemek için zaman sahip değil ile ilgili bir şey var gibi görünüyor
EventSchema.index({ pkey: 1 }, { unique: true }); 
+0

URL'sinde olayı/{: horible_key} 'i verir - Ben bunu yaptım, ancak sonuçlar aynı pkey değerleri eklenmiş iki kayıt aldığımla aynı ... Hızlı bir test olarak önerinizi de denedim ve kaldırdım alan tanımından da benzersiz (bunu değiştirmemi istediğinizden emin değildim), ama bu da iki kayıt ekler ... :( –

0

Db'de bazı kayıtlar ekledikten sonra benzersiz bir dizin oluşturma (şema düzeyinde) yaptığınız anlaşılıyor.

kaçınarak yinelenenlere aşağıdaki yolu takip edin -

1) sizin db damla:

$ Mongo

> use <db-name>; 

> db.dropDatabase(); 

2) şimdi şema düzeyinde veya db seviyesinde indeksleme yapmak

var EventSchema = new mongoose.Schema({ 
     pkey: { type: String, unique: true }, 
     device: { type: String, required: true }, 
     name: { type: String, required: true }, 
     owner: { type: String, required: true }, 
     description: { type: String, required: true }, 
    }); 

Aynı pKey değeriyle yinelenen kayıt ekleme işlemini önleyecektir.

ve dizinin sağlanması için db.db_name.getIndexes() komutunu kullanın.

Bunun yardımcı olacağını umuyorum.