Faire le plus (et la partie la plus difficile) de ce que vous voulez peut facilement être fait dans MongoDB. La dernière étape lors du retour de "basique", "premium" ou "standard" peut également être effectuée, mais je pense que cela ne vaut pas la peine car c'est trivial dans Go.
Dans MongoDB, utilisez le framework d'agrégation
pour ça. Ceci est disponible dans le mgo
package via Collection.Pipe()
méthode. Il faut lui passer une tranche, chaque élément correspond à une étape d'agrégation. Lisez cette réponse pour plus de détails :Comment obtenir un agrégat à partir d'une collection MongoDB
Revenons à votre exemple. Votre GetEventLevel()
méthode pourrait être implémentée comme ceci :
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
}
Si vous n'avez besoin que d'au plus un EventBoost
(ou il peut ne pas y en avoir plus en même temps), utilisez $limit
étape pour limiter les résultats à un seul, et utilisez $project
pour récupérer uniquement le level
champ et rien de plus.
Utilisez ce pipeline pour la simplification/optimisation mentionnée ci-dessus :
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
},
},
})