根据文档(http://godoc.org/launchpad.net/mgo/v2),如果您使用 Upsert 方法,您可以获得“Upserted”文档的 ID。
还有一个不提供此功能的 Insert 方法。
这是为什么?如果我想执行插入而不是 Upsert 怎么办?(或者永远不会有任何正当理由想要这样做?我开始怀疑了。)
根据文档(http://godoc.org/launchpad.net/mgo/v2),如果您使用 Upsert 方法,您可以获得“Upserted”文档的 ID。
还有一个不提供此功能的 Insert 方法。
这是为什么?如果我想执行插入而不是 Upsert 怎么办?(或者永远不会有任何正当理由想要这样做?我开始怀疑了。)
你用bson
. NewObjectId()
生成要插入的 ID。
这是您插入新文档的方式:
i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})
由于您在发出 时不知道是要插入还是更新Upsert
,所以生成一个 ID 只是为了在查询后立即删除它是多余的(以防发生更新)。这就是它在数据库端生成并在适用时返回给您的原因。
这根本不应该发生,mgo 应该插入并返回 Id,因为,如果我们从应用程序本身生成 ObjectId,如果应用程序重新启动,Object Id 生成器将从头开始,一次又一次地生成相同的 ID ,从而更新数据库中的现有记录。
这是错误的,MGO 应该依赖数据库来生成这些 ID 并更新对象或立即返回插入对象的 objectId,就像绑定到 MongoDB 的其他语言在 Python 或 Java 中所做的那样。
您可以随时尝试 Upsert 函数来获取生成的 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
这是我拥有的示例代码并且工作正常......