ほとんど (そして最も難しい部分)あなたが望むことのほとんどはMongoDBで簡単に行うことができます。 「ベーシック」、「プレミアム」、「スタンダード」を返すときの最後のステップも実行できる可能性が高いですが、Goでは些細なことなので面倒な価値はないと思います。
MongoDBでは、集約フレームワーク
を使用します このため。これはmgo
で利用できます Collection.Pipe()
を介してパッケージ化する
方法。それにスライスを渡す必要があります。各要素は集計ステージに対応します。詳細については、この回答をお読みください:MongoDBコレクションから集計を取得する方法
例に戻ります。 GetEventLevel()
メソッドは次のように実装できます:
func (dao *campaignDAO) GetEventLevel(eventID string) (string, error) {
c := sess.DB("").C("eventboosts") // sess represents a MongoDB Session
now := time.Now()
pipe := c.Pipe([]bson.M{
{
"$match": bson.M{
"_event_id": eventID, // Boost for the specific event
"is_published": true, // Boost is active
"start_date": bson.M{"$lt": now}, // now is between start and end
"end_date": bson.M{"$gt": now}, // now is between start and end
},
},
{
"$lookup": bson.M{
"from": "campaigns",
"localField": "_campaign_id",
"foreignField": "_id",
"as": "campaign",
},
},
{"$unwind": "$campaign"},
{
"$match": bson.M{
"campaign.is_published": true, // Attached campaign is active
},
},
})
var result []*EventBoost
if err := pipe.All(&result); err != nil {
return "", err
}
if len(result) == 0 {
return "standard", nil
}
return result[0].Level, nil
}
最大で1つのEventBoost
のみが必要な場合 (または同時にそれ以上ない場合もあります)、$limit
を使用します 結果を1つに制限し、$project
を使用するステージ level
のみをフェッチする フィールドとそれ以上のものはありません。
上記の単純化/最適化には、このパイプラインを使用してください:
pipe := c.Pipe([]bson.M{
{
"$match": bson.M{
"_event_id": eventID, // Boost for the specific event
"is_published": true, // Boost is active
"start_date": bson.M{"$lt": now}, // now is between start and end
"end_date": bson.M{"$gt": now}, // now is between start and end
},
},
{
"$lookup": bson.M{
"from": "campaigns",
"localField": "_campaign_id",
"foreignField": "_id",
"as": "campaign",
},
},
{"$unwind": "$campaign"},
{
"$match": bson.M{
"campaign.is_published": true, // Attached campaign is active
},
},
{"$limit": 1}, // Fetch at most 1 result
{
"$project": bson.M{
"_id": 0, // We don't even need the EventBoost's ID
"level": "$level", // We do need the level and nothing more
},
},
})