Golang/mgo: Почему mgo не возвращает идентификатор вставленного документа?
В соответствии с документацией (http://godoc.org/launchpad.net/mgo/v2) вы можете получить идентификатор вашего документа "Upserted", если вы используете метод Upsert.
Существует также метод Insert, который не предоставляет эту функцию.
Почему это? Что делать, если я хочу выполнить Insert вместо Upsert? (или не было бы никакой веской причины, чтобы хотеть это сделать? Я начинаю удивляться.)
Ответы
Ответ 1
Вы используете bson
. NewObjectId()
для создания идентификатора, который нужно вставить.
Вот как вы введете новый документ:
i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})
Так как вы не знаете, собираетесь ли вы вставлять или обновлять при выпуске Upsert
, было бы излишним генерировать идентификатор, чтобы просто удалить его сразу после запроса (в случае обновления). Именно поэтому он сгенерировал db-сторону и вернулся к вам, когда это применимо.
Ответ 2
Это не должно происходить вообще, mgo должно вставлять и возвращать Id, поскольку, если мы сгенерировали ObjectId из самого приложения, если приложение перезагрузилось, генератор идентификатора объекта начнет с самого начала генерировать те же идентификаторы снова и снова, тем самым обновляя существующие записи в базе данных.
Это неправильно, MGO должен полагаться на базу данных при генерации этих идентификаторов и обновлении объекта или возвращении объекта object сразу после вставленного объекта, так же как и другие языки, привязанные к MongoDB, как на Python или Java.
Ответ 3
Вы всегда можете попробовать функцию Upsert, чтобы получить сгенерированный идентификатор.
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
Это пример кода, который у меня есть и работает нормально.....