de bu işlevsellik sağlamaz bir ekleme yöntemi yoktur.
Neden? Ya bir Upsert yerine bir Insert yapmak istersem? (Ya da hiç bunu yapmak ister herhangi geçerli bir neden olmaz? Merak etmeye başladım.)
cevap
Sen bson
kullanın. Eklenecek bir kimlik oluşturmak için NewObjectId()
. Eğer bir Upsert
kesilirken eklemek veya güncellemek için gidiyoruz bilmiyorum beri
i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})
bir oluşturmak için gereksiz olacaktır:
Bu
Eğer yeni bir belge yerleştirin şey mi Kimlik, sorgudan hemen sonra bırakmak için (bir güncelleme olduğunda). Bu yüzden db tarafı oluşturuldu ve uygulanabilir olduğunda size geri döndü.Bu hiç olmamalı, mgo uygulamanızın kendisinden yaratılmış olsaydık, mA, uygulamayı yeniden başlatır ve döndürür. Çünkü, uygulama yeniden başlatılırsa, Nesne Kimliği üreteci, baştan başlayarak aynıdır. Kimlikler tekrar ve tekrar, böylece veritabanında mevcut kayıtları günceller. Bu yanlıştır, MGO, bu ID'lerin oluşturulmasında ve nesnenin güncellenmesinde veya MongoDB'ye bağlanan diğer dillerin Python veya Java'da olduğu gibi hemen eklenen nesnenin objectId öğesinin döndürülmesinde veritabanına güvenmelidir.
yerine bson.NewObjectId 'arasında ise()' biri 'kullanmak bson.NewObjectIdWithTime (time.Now())' Uygulamayı yeniden başlatma sorunu sorun olmaz, değil mi? –
Bu, ObjectID belgesinin okunması için bir zaman damgası ve PID içeren bir ObjectID oluşturma yöntemi olarak oldukça olanaksız görünüyor. Örnek PID'yi almanız ve sistem saatinizi sıfırlamanız durumunda, potansiyel olarak ObjectID çatışmalarını alabilirsiniz, aksi takdirde para cezanız olabilir. https://docs.mongodb.com/manual/reference/method/ObjectId/ –
Hep oluşturulan kimliğini almak için Upsert işlevini deneyebilirsiniz.
db := service.ConnectDb()
sessionCopy := db.Copy()
defer sessionCopy.Close() // clean up
collection := sessionCopy.DB(service.MongoDB.DTB).C(MessageCol.tbl)
log.Println("before to write: ", msg)
// Update record inserts and creates an ID if wasn't set (Returns created record with new Id)
info, err := collection.Upsert(nil, msg)
if err != nil {
log.Println("Error write message upsert collection: ", err)
return MessageMgo{}, err
}
if info.UpsertedId != nil {
msg.Id = info.UpsertedId.(bson.ObjectId)
}
// gets room from mongo
room, err := GetRoom(msg.Rid)
if err != nil {
return msg, err
}
// increments the msgcount and update it
room.MsgCount = room.MsgCount + 1
err = UpdateRoom(room)
if err != nil {
return msg, err
}
return msg, err
Bu örnek bir
nasıl "foo" yerini alabilecek Ben ve çalışıyor kod ..... edilir: bir yapı ile "bar" Ben zaten oluşturduk? – Acidic
"Uygulama yeniden başlatılırsa, nesne kimliği jeneratör böylece veritabanında mevcut kayıtları güncelleyerek, tekrar tekrar aynı kimliklerini oluşturma baştan başlayacaktır." Bu ikinci cevap üzerine yazılmıştır, GERÇEKTEN önemli ve cevapta belirtilmemiş. Gelecekte insanlar için bu bilgiyi ekleyerek cevabı düzenlemelisiniz. – cjf93
@ cjf93 Bu doğru değil (daha fazla?). Bson.ObjectId uygulamasına bakarsanız, şimdiki zamanı dikkate aldığını göreceksiniz. Bu aynı zamanda burada açıklanmıştır: https://github.com/go-mgo/mgo/issues/392 –