doulai7239 2017-05-23 12:28
浏览 36
已采纳

如何使用mgo在单个集合中处理多种类型

I'm very new to golang and try to write a simple event-sourcing user-management webapi using mongodb as backing database. Now i have User, which looks something like this:

type User struct {
Id       bson.ObjectId `json:"id" bson:"_id"`
UserName string        `json:"username" bson:"username"`
Email    string        `json:"email" bson:"email"`
PwdHash  string        `json:"pwd_hash" bson:"pwd_hash"`
FullName string        `json:"fullname" bson:"fullname"`
}

and three events, happening to user, when somebody uses api:

type UserCreatedEvent struct {
    UserId         bson.ObjectId `json:"id" bson:"_id"`
    //time when event was issued
    CreatedEpoch   time.Time     `json:"created_epoch" bson:"created_epoch"`
    //id of user that made a change
    IssuedByUserId bson.ObjectId `json:"issuedby_userid" bson:"issuedby_userid"`
}

type UserDeletedEvent struct {
    UserId         bson.ObjectId `json:"id" bson:"_id"`
    CreatedEpoch   time.Time     `json:"created_epoch" bson:"created_epoch"`
    //id of user that made a change
    IssuedByUserId bson.ObjectId `json:"issuedby_userid" bson:"issuedby_userid"`
}

type UserUpdatedEvent struct {
    UserId         bson.ObjectId `json:"id" bson:"_id"`
    CreatedEpoch   time.Time     `json:"created_epoch" bson:"created_epoch"`
    //id of user that made a change
    IssuedByUserId bson.ObjectId `json:"issuedby_userid" bson:"issuedby_userid"`
    ChangedFieldName     string  `json:"changed_field_name" bson:"changed_field_name"`
    NewChangedFieldValue string  `json:"new_changed_field_value" bson:"new_changed_field_value"`
}

Now i'm stuck on saving and retrieving events from db. The problem is i want to store them in a single collection, so that i have a full plain history of user modifications. But i can't find how to correctly store event type name as a mongo document field and then use it in searches. What is the idiomatic go-way to do this?

I'll be gratefull for any help.

  • 写回答

1条回答 默认 最新

  • dongweicha6077 2017-05-23 13:35
    关注

    What's nice about a non-relational database is that a little redundancy is OK and is faster for retrieval since you're not joining things together. You could just add your bottom three objects as properties on your User in whatever fashion makes sense for you and your data. Then you wouldn't need to store the UserId on those objects either.

    If you need to search over the Events quickly, you could create another collection to hold them. You'd be inserting to two collections, but retrieval times/logic should be pretty good/easy to write.

    Your new Event would be something like:

    type UserEventType int
    
    const (
        Created UserEventType = iota
        Deleted
        Updated
    )
    
    type UserEvent struct {
        UserId               bson.ObjectId `json:"id" bson:"_id"`
        CreatedEpoch         time.Time     `json:"created_epoch" bson:"created_epoch"`
        //id of user that made a change
        IssuedByUserId       bson.ObjectId `json:"issuedby_userid" bson:"issuedby_userid"`
        ChangedFieldName     string        `json:"changed_field_name,omitempty" bson:"changed_field_name,omitempty"`
        NewChangedFieldValue string     `json:"new_changed_field_value,omitempty" bson:"new_changed_field_value,omitempty"`
        EventType            UserEventType `json:"user_event_type" bson:"user_event_type"`
    }
    

    Notice the omitempty on the fields that are optional depending on the type of event.

    You really aren't supposed to store different objects in the same collection. Here's a line from the Mongo documentation:

    MongoDB stores documents in collections. Collections are analogous to tables in relational databases.

    In case you aren't familiar with relational databases, a table would essentially represent one type of object.

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

报告相同问题?

悬赏问题

  • ¥15 我下载图形界面重启完就变成这样了,打字也打不了,动也动不了,该怎么解决(操作系统-centos)
  • ¥15 VBA中在窗体中遍历所有checkbox控件,提取出被选中的checkbox的caption值
  • ¥15 在Ubuntu上有什么命令,或者是系统文件能告诉我链接nvme ssd的pcie槽位是不是支持热插拔功能?
  • ¥15 ansys license许可证问题
  • ¥20 QQ号和密码都能正常登录微信 QQ号和密码登录微信显示密码错误
  • ¥15 qiankun主应用注册子应用提示跨域
  • ¥15 单片机RTOS Kernel与应用分离开发,Kernel如何调起应用?
  • ¥15 快手小店商家版APP怎么第三方APP跳转到指定用户聊天界面
  • ¥15 为什么AVL fire软件仿真时的步长改变了,仿真结果也会改变
  • ¥100 如何帮我写一个java小游戏