Golang / mgo:为什么mgo不返回插入文档的ID?

时间:2012-08-17 16:09:37

标签: mongodb go mgo

根据文档(http://godoc.org/launchpad.net/mgo/v2),如果您使用Upsert方法,则可以获取“Upserted”文档的ID。

还有一种不提供此功能的Insert方法 这是为什么?如果我想执行Insert而不是Upsert怎么办? (或者永远不会有任何正当理由想要这样做?我开始怀疑。)

3 个答案:

答案 0 :(得分:44)

您使用bsonNewObjectId()生成要插入的ID。

这是您插入新文档的方式:

i := bson.NewObjectId()
c.Insert(bson.M{"_id": i, "foo": "bar"})

由于您在发出Upsert时不知道是否要插入或更新,因此生成ID只是为了在查询后立即删除它(如果发生更新,那将是多余的)。这就是它生成db-side并在适用时返回给你的原因。

答案 1 :(得分:2)

这根本不应该发生,mgo应该插入并返回Id,因为,如果我们从应用程序本身生成ObjectId,如果应用程序重新启动,Object Id生成器将从头开始生成相同的ID一次又一次,从而更新数据库中的现有记录。

这是错误的,MGO应该依赖数据库生成这些ID并更新对象或立即返回插入对象的objectId,就像在Python或Java中绑定到MongoDB的其他语言一样。

答案 2 :(得分:1)

您始终可以尝试使用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

这是我的示例代码并且工作正常.....