空的或不需要的结构字段

Posted

技术标签:

【中文标题】空的或不需要的结构字段【英文标题】:Empty or not required struct fields 【发布时间】:2014-08-04 16:10:09 【问题描述】:

我有两个结构代表将被插入到 mongodb 数据库中的模型。一个结构(投资)将另一个结构(组)作为其字段之一。

type Group struct 
    Base
    Name string `json:"name" bson"name"`


type Investment struct 
    Base
    Symbol string `json:"symbol" bson:"symbol" binding:"required"`
    Group  Group  `json:"group" bson:"group"`
    Fields bson.M `json:"fields" bson:"fields"`

我遇到的问题是在投资模型中,组不是必需的。如果没有组,我认为最好不要将其插入数据库中。在 Go 中处理这样的数据库模型的最佳方法是什么?

【问题讨论】:

这不是我的专业领域,但您可能想调查json.Marshaler golang.org/pkg/encoding/json/#Marshaler 它可以让您为 json 定义自定义编组行为,这应该(通过一些努力)允许您不写基于某种逻辑的给定字段。 结构标签:json: "omitempty" 应该可以解决问题,根据记忆。 【参考方案1】:

tl;dr:使用,omitempty,如果您需要担心zero value 和空/未指定之间的区别,请使用do what the GitHub API does and use a pointer。


jsonbson 都支持 ,omitempty 标记。对于 json,“空值是 false、0、任何 nil 指针或接口值,以及任何长度为零的数组、切片、映射、或字符串”(json docs )。对于 bson,,omitempty 的意思是“仅包含未将类型设置为零值或空切片或映射的字段”,zero values 包含空字符串和空指针 (bson docs)。

所以如果你真的需要一个 Group 结构体,你可以放一个 *Group 代替,当指针为 nil 时它不会被存储。如果Investment 只需要保存组的名称,那就更简单了:"" 作为组名称可以防止存储组密钥。

bson 默认已经使用小写的字段名称,因此您可以在它们匹配时从结构标记中省略它。 json 将默认为大写名称,因此如果需要小写,请在标记中指定小写名称。

所以,最好的情况,也许你可以使用:

type Investment struct 
    Base
    Symbol string `json:"symbol" binding:"required"`
    Group string  `json:"group,omitempty" bson:",omitempty"`
    Fields bson.M `json:"fields"`

如果您遇到类型(“”、0、false 等)的零值与“未指定”不同的字段,您可以do what the GitHub API does and put pointers in your structures--本质上是*Group 的扩展把戏。

【讨论】:

不是 Mongo 用户,如有错误请纠正我。阅读了 GitHub 关于可省略字段指针的帖子和建议,omitempty 的评论,并挖掘了相关文档,看起来它会起作用。 您不需要在 JSON 字段的标签中指定小写名称。根据文档:To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. 如果你只是解码你不必担心大小写,但如果你想编组/编码并且在JSON中出现小写名称,你必须使用结构标签来询问为它。【参考方案2】:

避免 strut 字段为空时编组 -

结构体字段可以是原始类型(字符串、整数、布尔值等),甚至是另一种结构体类型。

所以有时我们不希望结构的字段 如果它们为空,则进入 json 数据(可能用于数据库插入或外部 api 调用)

示例

type Investment struct 
    Base
    Symbol string `json:"symbol" bson:"symbol" binding:"required"`
    Group  Group  `json:"group" bson:"group"`
    Fields bson.M `json:"fields" bson:"fields"`

如果我们希望 SymbolGroup 可能包含空值(0、false、nil 指针、零大小接口/结构),那么我们可以在 json 编组中避免它们如下所示。

type Investment struct 
    Base
    Symbol string `json:"symbol,omitempty" bson:"symbol,omitempty" binding:"required"`
    Group  *Group  `json:"group,omitempty" bson:"group,omitempty"`
    Fields bson.M `json:"fields" bson:"fields"`

她的“Group”字段是指向 Group 结构的指针,每当它指向 nil 指针时,它将从 json 编组中省略。

显然我们将在 Group 字段中填充值,如下所示。

// declared investment variable of type Investment struct

 investment.Group = &groupData

【讨论】:

以上是关于空的或不需要的结构字段的主要内容,如果未能解决你的问题,请参考以下文章

使 LEAST() 函数返回一个非空值

JQ:如果字段为空或不存在,如何删除?

优化Mysql字段尽可能用NOT NULL

Oracle 查询某字段值为空的数据

mongodb使用条件查找文档并更新相应文档中的另一个字段

过滤字段值或不存在