dongwei4096 2017-11-07 13:18
浏览 62
已采纳

如何在Golang结构中使用temptempty标志更新Mongodb字段

I am working on a Coupon form in which I have some optional fields.

Introduction:

All the form field values are received as JSON and mapped into a Golang structure. In the structure, I have added an "omitempty" flag with every field. So only those form values are mapped which have some appropriate value, rest of the values like 0, " ", false are ignored by the structure.

Here is the Golang structure

type Coupon struct {
    Id               int    `json:"id,omitempty" bson:"_id,omitempty"`
    Name             string `json:"name,omitempty" bson:"name,omitempty"`
    Code             string `json:"code,omitempty" bson:"code,omitempty"`
    Description      string `json:"description,omitempty" bson:"description,omitempty"`
    Status           bool   `json:"status" bson:"status"`
    MaxUsageLimit    int    `json:"max_usage_limit,omitempty" bson:"max_usage_limit,omitempty"`
    SingleUsePerUser bool   `json:"single_use_per_user,omitempty" bson:"single_use_per_user,omitempty"`
}

Problem:

  1. When I save this form for the very first time, the form values that are appropriate are saved into the Mongodb.

  2. Now I want to update that form and suppose there is a check box, which was checked at the time of saving data. While updating form, the checkbox is unchecked and form is submitted to save. Now as I have applied "omitempty" flag in the structure, so its not mapping the empty value to the checkbox field. Since the value is not mapped into the structure, its not getting saved into the Database.

  3. When a user edits the form for the second time, it sees the same check box as checked. (But practically, the value should be updated to the DB and the check box should be displayed as unchecked.)

  4. I am using the same form data (in JSON format) in a REST API. In API, while updating form data, if I mention only those values which are required and don't pass the values which I don't want to update, then MongoDB is overriding the whole document with the provided required values(Even those values are also being overridden which I don't want to update as well as don't pass in the API).

Requirement:

In future, I want to expose the REST API, So I don't want this thing to be happened there. That is why I don't want to remove "omitempty" flag from the structure fields.

Is there any way to save the empty form values or API data fields to the DB while using omitempty flag in the structure?

Thanks!

  • 写回答

2条回答 默认 最新

  • dongxi5494 2017-11-08 08:49
    关注

    A value of bool type has 2 possible values: false and true. And you want to "communicate" 3 different states with a bool field, namely to not update the field, to set the field to false and to set the field to true. This is obviously not possible.

    Same thing goes for int values: a value of 0 cannot represent 2 different choices, namely to not update the field and to set it to 0.

    If you want to keep the omitempty options in the tag values, then to make it work, you have to change the fields to pointers:

    type Coupon struct {
        Id               *int    `json:"id,omitempty" bson:"_id,omitempty"`
        Name             string `json:"name,omitempty" bson:"name,omitempty"`
        Code             string `json:"code,omitempty" bson:"code,omitempty"`
        Description      string `json:"description,omitempty" bson:"description,omitempty"`
        Status           *bool   `json:"status" bson:"status"`
        MaxUsageLimit    *int    `json:"max_usage_limit,omitempty" bson:"max_usage_limit,omitempty"`
        SingleUsePerUser *bool   `json:"single_use_per_user,omitempty" bson:"single_use_per_user,omitempty"`
    }
    

    The way it works is that if the pointer is nil, it will be left out (this is the "omitempty" option). If the field is a non-nil pointer, it will be updated to the pointed value.

    So for example if you want to exclude a bool field, then the *bool value should / will be nil. If you want to set / update it to false, it must be a pointer to a false value. If you want to set / update it to true, it must be a pointer to a true value.

    In general, any type whose zero value is possible and should be counted with, you can only handle the "it is being the zero value" and "it is missing from the input" if you make it a pointer, and the nil value of the pointer will denote the "missing from the input" case, while a non-nil pointer to the zero value will denote the "it is being the zero value" case. So in the above example if the string fields could also take the empty string value (""), then you have to also make them pointers.

    Note that you can also achieve this using custom marshaling and unmarshaling logic, but that is more cumbersome, and using pointers gives you this automatically.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突