web-dev-qa-db-ja.com

mgoが挿入されたドキュメントのIDを返さないのはなぜですか?

ドキュメント( http://godoc.org/launchpad.net/mgo/v2 )によると、Upsertメソッドを使用すると、「Upserted」ドキュメントのIDを取得できます。

この機能を提供しないInsertメソッドもあります。
何故ですか?アップサートの代わりに挿入を実行したい場合はどうなりますか? (または、それを実行したい正当な理由はありませんか?私は疑問に思い始めています。)

25

bson . NewObjectId() を使用して、挿入するIDを生成します。

これは、新しいドキュメントを挿入する方法です。

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

Upsertを発行するときに挿入するのか更新するのかわからないため、クエリの直後にIDをドロップするだけでIDを生成する必要はありません(更新が発生した場合)。そのため、db側で生成され、該当する場合は返されます。

46
thwd

これはまったく発生しないはずです。アプリケーション自体からObjectIdを生成した場合、アプリケーションを再起動すると、オブジェクトIDジェネレーターが最初から同じIDを生成し始めるため、mgoはIDを挿入して返す必要があります。 、したがって、データベース内の既存のレコードを更新します。

それは間違っています。MGOは、MongoDBにバインドする他の言語がPythonまたはJavaで行うのと同じように、これらのIDを生成してオブジェクトを更新するか、挿入されたオブジェクトのobjectIdをすぐに返す際にデータベースに依存する必要があります。

2
Mohamed Ibrahim

生成されたIDを取得するには、いつでも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

これは私が持っているサンプルコードであり、正常に動作します。