由于mgo / txn中没有Upsert,当我不知道文档是否已存在时,我正在执行Insert后跟Update。像这样(记住这是一个简单的例子,实际上我也会改变不同的文件) -
ops := []txn.Op{{
C: "test",
Id: t.Id,
Insert: t,
}, {
C: "test",
Id: t.Id,
Update: bson.M{"$set": bson.M{"num": 123}},
}}
这很好用。不幸的是,它需要我确切地知道哪些字段已被更改。我通常在Save()函数中运行它,它接收一个对象并保存一堆相关文档,所以我通常不知道哪些字段已被更改。我试着做这样的事情 -
ops := []txn.Op{{
C: "test",
Id: t.Id,
Insert: t,
}, {
C: "test",
Id: t.Id,
Update:t,
}}
但这似乎不起作用,因为我得到“修饰符和非修饰符不能混合”错误。我想出的唯一解决方案是“$ set”每个字段 -
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}},
}}
但这似乎......笨重。我错过了什么吗?有没有办法更新整个文档?
答案 0 :(得分:2)
虽然看起来有点可疑,因为您将重新发送所有内容,但您可以通过将值本身提供给$set
来设置值中的每个字段:
{
C: "test",
Id: t.Id,
Update: bson.M{"$set": t},
}
另请注意,即使您选择手动发送值,也没有理由在多个操作中发送它们;这会奏效:
{
C: "test",
Id: t.Id,
Update: bson.M{"$set": bson.M{"foo": 1, "bar": 2}},
}
最后,请记住,当您将文档与交易机制一起使用时,它会获得机器本身所需的额外字段。如果用一些自定义内容替换整个文档,这些字段将会消失,并且txn包将无法正常运行。