de meeste doen (en het moeilijkste deel) van wat je wilt, kan eenvoudig worden gedaan in MongoDB. De laatste stap bij het teruggeven van "basis", "premium" of "standaard" kan hoogstwaarschijnlijk ook worden gedaan, maar ik denk dat het de moeite niet waard is, want dat is triviaal in Go.
Gebruik in MongoDB het Aggregation framework
voor deze. Dit is beschikbaar in de mgo
pakket via de Collection.Pipe()
methode. Je moet er een segment aan doorgeven, elk element komt overeen met een aggregatiestadium. Lees dit antwoord voor meer details:Een aggregaat uit een MongoDB-verzameling halen
Terug naar je voorbeeld. Uw GetEventLevel()
methode kan als volgt worden geïmplementeerd:
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
}
Als u maximaal één EventBoost
. nodig heeft (of misschien niet meer tegelijk), gebruik $limit
stap om de resultaten tot één enkele te beperken en gebruik $project
om alleen het level
op te halen veld en niets meer.
Gebruik deze pijplijn voor de bovengenoemde vereenvoudiging / optimalisatie:
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
},
},
})