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.

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

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格