type NoteUpdate struct {
ID string `json:"id,omitempty" bson:"_id,omitempty"`
Title string `json:"title" bson:"title,omitempty"`
Content string `json:"content" bson:"content,omitempty"`
ChangedAt int64 `json:"changed_at" bson:"changed_at"`
}
例如,如果我有
noteUpdate := NoteUpdate{ Title: "New Title" }
然后,我希望存储文档中唯一的“标题”字段将被更改。
我需要写类似
collection.FindOneAndUpdate(context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
// I need to encode non-empty fields here
bson.NewDocument(bson.EC.SubDocument("$set", bson.NewDocument(...)))
)
问题是我不想用bson.EC.String(...)或手动编码每个非空字段bson.EC.Int64(...)。我尝试使用bson.EC.InterfaceErr(...)但出现错误
无法为* models.NoteUpdate类型创建元素,请尝试使用bsoncodec.ConstructElementErr
不幸的是,bsoncodec中没有这样的功能。我发现的唯一方法是创建包装器
type SetWrapper struct {
Set interface{} `bson:"$set,omitempty"`
}
并像这样使用
partialUpdate := &NoteUpdate{
ID: "some-note-id",
Title: "Some new title",
}
updateParam := SetWrapper{Set: partialUpdate}
collection.FindOneAndUpdate(
context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
updateParam,
)
它可以工作,但是使用bson / bsoncodec文档构建器是否可以实现相同的目的?
UPD。我的问题的全部内容:我编写了REST端点,用于 部分 更新“注释”文档(存储在MongoDB中)。我现在拥有的代码:
var noteUpdate models.NoteUpdate
ctx.BindJSON(¬eUpdate)
//omit validation and errors handling
updateParams := services.SetWrapper{Set: noteUpdate}
res := collection.FindOneAndUpdate(
context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
updateParams,
findopt.OptReturnDocument(option.After),
)
我想要的代码
var noteUpdate models.NoteUpdate
ctx.BindJSON(¬eUpdate)
//omit validation and errors handling
res := collection.FindOneAndUpdate(
context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
bson.NewDocument(
//bsoncodec.ConstructElement doesn't exists
bsoncodec.ConstructElement("$set", ¬eUpdate)),
),
findopt.OptReturnDocument(option.After),
)
代码,我 不 希望有
var noteUpdate models.NoteUpdate
ctx.BindJSON(¬eUpdate)
//omit validation and errors handling
bsonNote := bson.NewDocument()
if noteUpdate.Title != "" {
bsonNote.Append(bson.EC.String("title", noteUpdate.Title))
}
if noteUpdate.Content != "" {
bsonNote.Append(bson.EC.String("content", noteUpdate.Content))
}
//..setting the rest of the fields...
res := collection.FindOneAndUpdate(
context.Background(),
bson.NewDocument(bson.EC.String("_id", noteUpdate.ID)),
bson.NewDocument(bson.EC.SubDocument("$set", bsonNote)),
findopt.OptReturnDocument(option.After),
)
因此,确切的问题是-是否有任何方法可以基于bson标签动态构建* bson.Document (没有像我的SetWrapper这样的预定义包装器)?