在go中使用预先构造的字符串作为bson.M进行mgo查询

时间:2016-09-12 09:21:37

标签: go marshalling bson mgo gorilla

此处更大的目标是在go中设置更新查询,仅设置在请求中发送给它的那些字段。

例如,我有一个文档要更新我允许用户更新可变数量的字段,只需在请求中指定它们就像这样 -

{
"field1": valueOfField1,
"field2": valueOfField2,
"field3": valueOfField3,
...
}

这里的问题是,当我使用json.Decode将此输入解码为具有大多数字段可选的自定义结构类型时,输入中不存在的值将保留为nil

我的结构看起来像这样 -

type Fields struct {
    Field1       string      `bson:"field1" json:"field1,omitempty"`
    Field2       string      `bson:"field2" json:"field2"`
    Field3       time.Time   `bson:"field3,omitempty" json:"field3,omitempty"`
    Field4       bool        `bson:"field4,omitempty" json:"field4,omitempty"`
...
}

现在在我的更新查询中,我说,

bson.M{"$set": bson.M{"field1": body.Field1, "field2": body.Field2, "field3": body.Field3, "field4": body.Field4, ...}}

问题是如果输入中不存在其中一个字段,它仍会覆盖数据库中的现有值并使其为空。

为了避免这种情况,我理想的是希望根据进来的字段动态构建这个{"field1": body.Field1, "field2": body.Field2, "field3": body.Field3, "field4": body.Field4, ...}部分。

为此,我做了json.Marshal输入,就像这样 -

finalbody, err := json.Marshal(body)

然后我试图在$ set字段中使用它作为 -

bson.M{"$set": string(finalbody)}

当然这给我一个错误说 - "修饰符对字段进行操作但是我们找到了一个字符串而不是"。 字符串就像bson一样完美。除了它不是bson.M,{"field1": valueOfField1, "field2": valueOfField2, "field3": valueOfField1, ...}

我哪里错了? [...表示'等等']

1 个答案:

答案 0 :(得分:1)

我通过Unmarshalling finalbody将解决方案发现到map [string] interface {}中,然后将其用作更新映射。

所以,

finalbody, err := json.Marshal(body)
var finalbodymap map[string]interface{}
json.Unmarshal(finalbody, &finalbodymap)

当然,您需要添加一些错误处理,以便最终代码如下所示 -

finalbody, err := json.Marshal(body)
    if err != nil {
        log.Println(err)
        return
    }
var finalbodymap map[string]interface{}
    if err = json.Unmarshal(finalbody, &finalbodymap); err != nil{
        log.Println(err)
    }

然后在更新查询中,我可以简单地写一下 -

bson.M{"$set": finalbodymap}

这里的一个问题是,虽然编组,它会设置任何时间。时间类型值为零,即" 0001-01-01T00:00:00Z"。我怀疑这种行为也可以用某些其他类型来观察。