避免在数据库中保存空白结构对象

Posted

技术标签:

【中文标题】避免在数据库中保存空白结构对象【英文标题】:Avoid to save blank struct object in db 【发布时间】:2022-01-12 11:46:00 【问题描述】:

我正在运行以下代码。当用户保存在数据库中然后保存空白地址时,我在保存之前将空结构分配给地址。我无法在地址结构的所有字段中添加省略号。如何避免在用户集合中保存空白地址对象

    package main

import (
    "context"
    "fmt"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type User struct 
    Id          int           `json:"id" bson:"_id,omitempty"`
    FirstName   string        `json:"first_name,omitempty" bson:"first_name,omitempty"`
    LastName    string        `json:"last_name,omitempty" bson:"last_name,omitempty"`
    FullName    string        `json:"full_name,omitempty" bson:"full_name,omitempty"`
    CompanyName string        `json:"company_name" bson:"company_name"`
    Address     AddressStruct `json:"address,omitempty" bson:"address,omitempty"`

type AddressStruct struct 
    Address      string `json:"address" bson:"address"`
    City         string `json:"city" bson:"city"`
    State        string `json:"state" bson:"state"`
    Zipcode      string `json:"zipcode" bson:"zipcode"`
    Apt          string `json:"apt" bson:"apt"`
    Default      bool   `json:"default" bson:"default"`
    Status       int8   `json:"status,omitempty" bson:"status,omitempty"`
    Country      string `json:"country,omitempty" bson:"country,omitempty"`
    ShortAddress string `json:"short_address" bson:"short_address"`


func main() 
    var user User
    user.FirstName = "Swati"
    user.LastName = "Sharma"
    user.FullName = "Swati Sharma"
    user.Address = AddressStruct
    client, ctx := ConnectDbWithNewDriver()
    defer client.Disconnect(ctx)
    a, b := DbInsertOne(client, user)
    fmt.Println("Section1", a, b)

func ConnectDbWithNewDriver() (client *mongo.Client, ctx context.Context) 
    ctx = context.Background()
    client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://127.0.0.1:27017").SetConnectTimeout(5*time.Second))
    if err != nil 
        fmt.Println("CreateSession: ", err)
        client.Disconnect(ctx)
        return
    
    return

func DbInsertOne(client *mongo.Client, data interface) (interface, error) 
    collection := client.Database("swatitest").Collection("users")
    insertResult, err := collection.InsertOne(context.TODO(), data)
    if err != nil 
        return nil, err
    
    return insertResult.InsertedID, nil

当我运行这段代码时,记录保存在数据库中,如下所示:


    "_id" : ObjectId("61af41b32214b16fe93435a6"),
    "first_name" : "Swati",
    "last_name" : "Sharma",
    "full_name" : "Swati Sharma",
    "company_name" : "",
    "address" : 
        "address" : "",
        "city" : "",
        "state" : "",
        "zipcode" : "",
        "apt" : "",
        "default" : false,
        "short_address" : ""
    

我想保存如下:


        "_id" : ObjectId("61af41b32214b16fe93435a6"),
        "first_name" : "Swati",
        "last_name" : "Sharma",
        "full_name" : "Swati Sharma",
        "company_name" : ""

【问题讨论】:

您在User 结构中使用omitempty 选项,因此您(或编写该代码的人)必须知道它。如果您不想保存空字符串,也可以在 AddressStruct 中使用 omitempty @icza 谢谢。我已经在用户对象下添加了带有地址的省略号,它工作正常,但是当我使用相同的代码保存 mongodb 新驱动程序 pkg "go.mongodb.org/mongo-driver/mongo" 时,它就不能那样工作了。 官方的mongodriver也支持omitempty选项。如果对您不起作用,请发布minimal reproducible example。 @icza 我已经用新的驱动程序更新了代码,但它没有给出所需的结果。 更新后的代码在AddressStruct 中没有omitempty 选项。例如,如果您不想要空的 city 属性,请将 omitempty 添加到 AddressStruct.City 字段。 【参考方案1】:

您可以使用omitempty bson 标签选项,所有 Go 驱动程序都会处理它,并且如果它的值是零值(对于原始类型),则不会保存该字段。

因此,将其添加到您不想保存为空字符串的所有字段中:

type AddressStruct struct 
    Address      string `json:"address" bson:"address,omitempty"`
    City         string `json:"city" bson:"city,omitempty"`
    State        string `json:"state" bson:"state,omitempty"`
    Zipcode      string `json:"zipcode" bson:"zipcode,omitempty"`
    Apt          string `json:"apt" bson:"apt,omitempty"`
    Default      bool   `json:"default" bson:"default,omitempty"`
    Status       int8   `json:"status,omitempty" bson:"status,omitempty"`
    Country      string `json:"country,omitempty" bson:"country,omitempty"`
    ShortAddress string `json:"short_address" bson:"short_address,omitempty"`

如果你不能修改结构体类型,那么就不要保存结构体值。创建您自己的类型(在其中添加omitempty),将结构值复制到其中,然后保存您自己的副本。

【讨论】:

感谢您的和,但我不能在地址的每个字段中添加省略号。我已经在问题中提到了这一点。还有其他方法吗? @Swati 如果无法修改结构类型,则不要保存结构值。创建自己的类型(在其中添加omitempty),将结构值复制到其中,然后保存自己的副本。

以上是关于避免在数据库中保存空白结构对象的主要内容,如果未能解决你的问题,请参考以下文章

iOS9 Xcode 7 - 核心数据 - 避免重复对象

Vue prop传一个对象给子组件,怎么避免子组件修改数据污染父组件?

访问类树层次结构中的对象时避免使用空指针

excel内存突然变大是啥原因?

Mybatis Mybatis缓存

性能 - NSValue 中的结构与容器对象