Melakukan paling banyak (dan bagian tersulit) dari apa yang Anda inginkan dapat dengan mudah dilakukan di MongoDB. Langkah terakhir ketika mengembalikan "dasar", "premium" atau "standar" kemungkinan besar juga dapat dilakukan, tetapi saya pikir itu tidak sebanding dengan kerumitannya karena itu sepele di Go.
Di MongoDB gunakan Kerangka kerja agregasi
untuk ini. Ini tersedia di mgo
paket melalui Collection.Pipe()
metode. Anda harus melewati sepotong untuk itu, setiap elemen sesuai dengan tahap agregasi. Baca jawaban ini untuk detail lebih lanjut:Cara Mendapatkan Agregat dari Koleksi MongoDB
Kembali ke contoh Anda. GetEventLevel()
. Anda metode dapat diimplementasikan seperti ini:
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
}
Jika Anda hanya membutuhkan paling banyak satu EventBoost
(atau mungkin tidak lebih pada saat yang sama), gunakan $limit
stage untuk membatasi hasil hanya satu, dan gunakan $project
untuk hanya mengambil level
lapangan dan tidak lebih.
Gunakan saluran ini untuk penyederhanaan/pengoptimalan yang disebutkan di atas:
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
},
},
})