duanguai2781 2017-01-30 15:04
浏览 37
已采纳

匿名结构返回空字段值

type (

    Id struct {
        // I previously forgot to add the `ID` field in my question, it is present in my code but not on this question as @icza pointed it out to me
        ID bson.ObjectId `json:"id" bson:"_id"`
    }

    User struct {
        // When using anonymous struct, upon returning the collection, each of the document will have an empty `id` field, `id: ""`
        Id
        Email string `json:"email" bson:"email"`
        ...
    }

    // This works
    User2 struct {
        ID bson.ObjectId `json:"id" bson:"_id"`
        Email string `json:"email" bson:"email"`
    }
)

I might not have fully understood the concept of anonymous structs yet. In the example above, when querying all users from a collection, the id field is going to be an empty string "". However, if I directly define the ID field in the User struct, the id shows up fine. Is this not what anonymous structs are for? Basically extending struct so you won't have to type them again and again?

More example:

type SoftDelete struct {
    CreatedAt time.Time `json:"created_at" bson:"created_at"`
    UpdatedAt time.Time `json:"updated_at" bson:"updated_at"`
    DeletedAt time.Time `json:"deleted_at" bson:"deleted_at"`
}

type UserModel struct {
    SoftDelete
}

type BlogPost struct {
    SoftDelete
}
  • 写回答

1条回答 默认 最新

  • du9843 2017-01-30 16:43
    关注

    The problem here is that fields having struct types (including embedded structs) appear as embedded documents in MongoDB. If you don't want this, you have to specify the "inline" bson flag when embedding a struct:

    User struct {
        Id           `bson:",inline"`
        Email string `json:"email" bson:"email"`
    }
    

    What the "inline" tag does is in MongoDB it "flattens" the fields of the embedded struct as if they were part of the embedder struct.

    Similarly:

    type UserModel struct {
        SoftDelete `bson:",inline"`
    }
    
    type BlogPost struct {
        SoftDelete `bson:",inline"`
    }
    

    Edit: the following section applies to the original Id type which embedded bson.ObjectId. The asker later clarified that this was just a typo (and edited the question since), and it is a named, non-anonymous field. Still think the info below is useful.

    One thing to note about your Id type: Your Id type also embeds bson.ObjectId:

    Id struct {
        bson.ObjectId `json:"id" bson:"_id"`
    }
    

    Id not just has a field of bson.ObjectId, but it embeds it. This matters because this way you Id type will have a String() method promoted from bson.ObjectId, and so will User which embeds Id. Having said that, it will be hard trying to print or debug values of type User, because you will always see it printed just as a single ObjectId.

    Instead you can make it a regular field in Id, embedding Id in User will still work as expected:

    Id struct {
        ID bson.ObjectId `json:"id" bson:"_id"`
    }
    

    See related question+asnwer: Enforce a type mapping with mgo

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度