dongmi1995 2014-06-27 15:27
浏览 56
已采纳

使用mgo.txn模拟Upsert

Since there's no Upsert in mgo/txn, I'm doing an Insert followed by an Update when I don't know whether a document already exists. Like this (bear in mind this is a simple example, in reality I would also be changing different documents) --

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"num": 123}},
}}

This works fine. Unfortunately it requires me to know exactly which fields have been changed. I normally run this inside a Save() function that receives an object and saves a bunch of related documents so I don't usually know what fields have been changed. I tried doing something like this instead --

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update:t,
}}

But that doesn't seem to work as I get a "Modifiers and non-modifiers cannot be mixed" error. The only solution I came up with was to "$set" every individual field --

ops := []txn.Op{{
    C:      "test",
    Id:     t.Id,
    Insert: t,
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"num": 123}},
}, {
    C:      "test",
    Id:     t.Id,
    Update: bson.M{"$set": bson.M{"other": 234}},
}}

But this seems... clunky. Am I missing something? Is there a way to update the whole document?

  • 写回答

1条回答 默认 最新

  • douyin9987 2014-06-27 18:06
    关注

    Although it looks a bit dubious given you'll be resending all the content over again, you can set every field in a value by offering the value itself to $set:

        {
            C:      "test",
            Id:     t.Id,
            Update: bson.M{"$set": t},
        }
    

    Also note that even if you choose to send the values manually, there's no reason to send them in multiple operations; this would work:

        {
            C:      "test",
            Id:     t.Id,
            Update: bson.M{"$set": bson.M{"foo": 1, "bar": 2}},
        }
    

    Finally, please keep in mind that when you use a document with the transaction machinery, it gets extra fields which are necessary for the machinery itself. If you replace the whole document with some custom content, these fields will go away, and the txn package won't behave properly.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测