MGO 驱动程序中的更新查询,适用于 bson.M,但不适用于自定义结构

Posted

技术标签:

【中文标题】MGO 驱动程序中的更新查询,适用于 bson.M,但不适用于自定义结构【英文标题】:Update query in MGO driver, works with bson.M, but does not work with custome structure 【发布时间】:2015-03-09 15:51:52 【问题描述】:

Mgo 和 golang 问题。

我又遇到了问题。我尝试更新数据库中的记录,但运行简单的命令visitors.UpdateId(v.Id, bson.M"$set": zscore); 其中zscoretype Zscore 的变量,不起作用。但是,如果我手动将 zscore 转换为 bson.M 结构,一切正常。

有人知道如何使用mgo 更新mongodb 中的记录,而无需手动将结构值转储到bson.M 中吗?

示例:

type Zscore struct 
    a float64 `bson:"a,omitempty" json:"a"`
    b float64 `bson:"b,omitempty" json:"b"`
    c float64 `bson:"c,omitempty" json:"c"`


v := Visitor
zscore := Zscore

visitors := updater.C("visitors")

for result.Next(&v) 
    zscore.a = 1
    zscore.b = 2
    zscore.c = 0

    //does not work
    if err := visitors.UpdateId(v.Id, bson.M"$set": zscore); err != nil    
            log.Printf("Got error while updating visitor: %v\n", err)
    

    //works
    set := bson.M
        "zscore.a": zscore.a,
        "zscore.b": zscore.b,
        "zscore.c": zscore.c,
    

    if err := visitors.UpdateId(v.Id, bson.M"$set": set); err != nil 
        log.Printf("Got error while updating visitor: %v\n", err)
    

【问题讨论】:

【参考方案1】:

我知道的所有 Go 编组包,包括 bson 包,都不会编组私有字段(以小写字母开头)。要解决此问题,只需将相关字段名称的首字母大写即可。

还请注意,除了上述问题之外,示例的第一部分不会以与第二部分等效的方式编组。 bson.M"$set": zscore 等价于bson.M"$set": bson.M"a": ... etc ...

【讨论】:

谢谢,现在很好用……你怎么知道字段不能是私有的? @Lukasz,可能来自documentation:“在结构值的情况下,只有导出的字段会被序列化。”一如既往,RTFM。 嗯...句子“小写的字段名称用作每个导出字段的键,但可以使用相应的字段标签更改此行为。”使文档不是 100% 明显。你会认为标签控制着什么是序列化的,什么不是。 这两句话是相加的,并不冲突。只有导出的字段会被序列化,而那些被序列化的字段可能会通过标签更改每个导出字段的键

以上是关于MGO 驱动程序中的更新查询,适用于 bson.M,但不适用于自定义结构的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 golang 的 mgo 包进行类似查询

使用 golang 和 mgo,如何在 MongoDB 中搜索一系列值?

带有 mgo 的 Go (golang) 中的 MongoDB:如何更新记录、确定更新是不是成功并在单个原子操作中获取数据?

如何使用 go mongo 驱动程序一起执行查找、区分和排序

mgo中的Golang Bson排序参数

.Net SqlCommand.ExecuteNonQuery 中的查询超时,适用于 SQL Server Management Studio