2017-05-23 7 views
1

私はgolangの新機能で、mongodbをバッキングデータベースとして使用して、簡単なイベントソース管理ユーザー管理webapiを作成しようとしています。今私は、DBからイベントを保存および取得にこだわっているmgoを使った単一のコレクションで複数のタイプを扱う方法

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"` 
} 

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"` 
} 

と誰かがAPIを使用して、ユーザーに起こって3つのイベント、:今、私はこのようになりますユーザーを持っています。問題は、それらを1つのコレクションに格納して、私はユーザーの変更の完全なプレーンな履歴を持っていることです。しかし、私は正しくどのようにmongoドキュメントフィールドとしてイベントの種類の名前を格納し、検索でそれを使用する方法を見つけることができません。これを行うための慣用的な道は何ですか?

私はどんな助けでも大歓迎です。

答えて

1

非リレーショナルデータベースについては、少し冗長性があり、検索に時間がかかるということがあります。 Userのプロパティとして、下部の3つのオブジェクトを追加するだけで、あなたとあなたのデータに合った方法で作成できます。次に、これらのオブジェクトにUserIdを格納する必要はありません。

Eventsをすばやく検索する必要がある場合は、別のコレクションを作成して保持することができます。あなたは2つのコレクションに挿入されますが、検索時間/ロジックはかなり良い/簡単に書く必要があります。

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"` 
} 

お知らせイベントの種類に応じて、オプションであるフィールド上omitempty

新しいEventはようなものになるだろう。

実際には、同じコレクション内に異なるオブジェクトを保存することは想定されていません。ここにMongoのドキュメントの行があります:

MongoDBはドキュメントをコレクションに格納します。コレクションはリレーショナルデータベースのテーブルに似ています。

リレーショナルデータベースに精通していない場合は、テーブルは基本的に1つのタイプのオブジェクトを表します。

+0

お返事ありがとうございます! これは、私が実装したいと思っているものに似たものです。質問は同じです:私はどのようにして、ある期間の歴史を検索しますか?私は3つの配列のプロパティで検索する必要がありますし、それは1つを検索するほど速くはないでしょうか?だから私はRDBMSからNoSQLに移行したのです。 –

+0

これらのオブジェクトを別々に保存することもできますが、オブジェクトごとに異なるコレクションで行う必要があります。あなたの質問には、ドキュメントベースのストアよりもRDBMSに似ています。あなたは、あなたがなぜその移行を行う必要があると思ったのかをさらに説明できますか? – Gavin

+0

私にとってRDBMSの主な問題は、書き込み(挿入)効率でした。私は、Go + Mongoを使って新しいバージョンのマイクロサービスを実装する予定であり、そのほとんどは毎秒10k +の挿入を処理する必要があります。挿入の大部分はこれらのイベントで、一部のオブジェクトの変更の履歴として保存されます。それらは毎週/毎日ですが、ユーザーは一定期間レポートを作成することもできます)。私の経験に基づいて、RDBMSはここではかなり遅く、スキーマの少ない自由を与えません。ですから、私の主な考えは、異なるタイプのオブジェクトを単一のコレクションに多分、エポックベースのIDで格納することでした。 –