英文:
Why does mgo not return the ID of inserted document?
问题
根据文档(http://godoc.org/launchpad.net/mgo/v2),如果使用Upsert方法,您可以获取“Upserted”文档的ID。
还有一个Insert方法,它不提供这个功能。
为什么会这样?如果我想执行Insert而不是Upsert怎么办?(或者根本没有任何有效的理由想要这样做吗?我开始怀疑了。)
英文:
According to the documentation (http://godoc.org/launchpad.net/mgo/v2) you can obtain the ID of your "Upserted" document if you use the Upsert method.
There is also an Insert method that does not provide this functionality.
Why is that? What if I want to perform an Insert instead of an Upsert? (or wouldn't ever be any valid reason to want to do that? I'm starting to wonder.)
答案1
得分: 47
你可以使用bson
.NewObjectId()
来生成一个要插入的ID。
以下是插入新文档的示例代码:
i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})
由于在执行Upsert
时无法确定是要插入还是更新,因此在查询之后生成一个ID然后立即丢弃它是多余的。这就是为什么它在数据库端生成并在适用时返回给你。
英文:
You use bson
.NewObjectId()
to generate an ID to be inserted.
This is how you'd insert a new document:
i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})
Since you don't know if you're going to insert or update when you issue an Upsert
, it would be superfluous to generate an ID just to drop it right after the query (in case an update happens). That's why it's generated db-side and returned to you when applicable.
答案2
得分: 3
这根本不应该发生,mgo应该插入并返回Id,因为如果我们从应用程序本身生成ObjectId,如果应用程序重新启动,ObjectId生成器将从头开始生成相同的ID,从而更新数据库中的现有记录。
这是错误的,MGO应该依赖于数据库来生成这些ID并更新对象,或者立即返回插入对象的objectId,就像其他绑定到MongoDB的语言(如Python或Java)一样。
英文:
This should not happen at all, the mgo should insert and return the Id, since, if we generated the ObjectId from the application itself, If the application is restarted, the Object Id generator will start from the beginning generating the same IDs again and again, thus updating existing records in the database.
That is wrong, MGO should rely on the database in generating those IDs and updating the object or returning the objectId of the inserted object immediately like what other languages binding to MongoDB does like in Python or Java.
答案3
得分: 1
你可以尝试使用Upsert函数来获取生成的ID。
db := service.ConnectDb()
sessionCopy := db.Copy()
defer sessionCopy.Close() // 清理
collection := sessionCopy.DB(service.MongoDB.DTB).C(MessageCol.tbl)
log.Println("写入之前:", msg)
// 更新记录并插入一个ID(如果没有设置ID,则返回带有新ID的创建记录)
info, err := collection.Upsert(nil, msg)
if err != nil {
log.Println("写入消息Upsert集合时出错:", err)
return MessageMgo{}, err
}
if info.UpsertedId != nil {
msg.Id = info.UpsertedId.(bson.ObjectId)
}
// 从Mongo获取房间
room, err := GetRoom(msg.Rid)
if err != nil {
return msg, err
}
// 增加msgcount并更新
room.MsgCount = room.MsgCount + 1
err = UpdateRoom(room)
if err != nil {
return msg, err
}
return msg, err
这是我拥有并且正常工作的示例代码.....
英文:
You can always try the Upsert function to get the generated ID.
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
This is a sample code I have and works fine.....
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论