我有这两个模型:
// EventBoost describes the model of a EventBoost type EventBoost struct { ID string `bson:"_id" json:"_id" valid:"alphanum,printableascii"` Name string `bson:"name" json:"name"` Description string `bson:"description" json:"description"` Level string `bson:"level" json:"level"` EventID string `bson:"_event_id" json:"_event_id" valid:"alphanum,printableascii"` StartDate time.Time `bson:"start_date" json:"start_date"` EndDate time.Time `bson:"end_date" json:"end_date"` IsPublished bool `bson:"is_published" json:"is_published"` CreatedBy string `bson:"created_by" json:"created_by"` CreatedAt time.Time `bson:"created_at" json:"created_at"` ModifiedAt time.Time `bson:"modified_at" json:"modified_at"` } // Event describes the model of an Event type Event struct { ID string `bson:"_id" json:"_id" valid:"alphanum,printableascii"` OldID string `bson:"old_id" json:"old_id" valid:"alphanum,printableascii"` ParentID string `bson:"_parent_id" json:"_parent_id" valid:"alphanum,printableascii"` Name string `bson:"name" json:"name"` Content string `bson:"content" json:"content"` Slug string `bson:"slug" json:"slug"` LocationID string `bson:"_location_id" json:"_location_id"` Price string `bson:"price" json:"price"` Categories []string `bson:"categories" json:"categories"` Tags []string `bson:"tags" json:"tags"` Organisers []string `bson:"organisers" json:"organisers"` Artists []string `bson:"artists" json:"artists"` Image string `bson:"image" json:"image"` IsPublished bool `bson:"is_published" json:"is_published"` IsProposed bool `bson:"is_proposed" json:"is_proposed"` CreatedBy string `bson:"created_by" json:"created_by"` CreatedAt time.Time `bson:"created_at" json:"created_at"` ModifiedAt time.Time `bson:"modified_at" json:"modified_at"` }
我想在查找 EventBoost时 仅返回一个 事件, 而不必使用Golang逻辑执行清理。因为实际上,返回的文档具有名为 event 的属性。我直接想要一个 事件 文档。
这是我的方法,需要返回 [] * models.Event :
// Boosted returns the boosted events func (dao *eventBoostDAO) Boosted() ([]*models.Event, error) { // Clone the session session := dao.session.Clone() defer session.Close() // Get the time now := time.Now() // Create the pipe pipe := session.DB(shared.DatabaseNamespace).C(dao.collection).Pipe([]bson.M{ { "$match": bson.M{ "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": "events", "localField": "_event_id", "foreignField": "_id", "as": "event", }, }, }) var result []*models.Event err := pipe.All(&result) if err != nil { return nil, err } return result, nil }
通过查看Mongo文档,我发现 $ project 应该可以帮助我完成我想做的事情,但是我没有找到如何将嵌套文档转换为最终文档。
您可以使用$unwind将event数组字段“转换” 为单个嵌入式文档,然后$replaceRoot将该event字段“提升” 为新的“根”:
$unwind
event
$replaceRoot
pipe := session.DB(shared.DatabaseNamespace).C(dao.collection).Pipe([]bson.M{ { "$match": bson.M{ "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": "events", "localField": "_event_id", "foreignField": "_id", "as": "event", }, }, {"$unwind": "$event"}, {"$replaceRoot": bson.M{ "newRoot": "$event" }}, })
如果给定存在多个事件,则此解决方案将正确处理EventBoost。
EventBoost