【问题标题】:Only return the looked up document with Mongo and Golang仅返回使用 Mongo 和 Golang 查找的文档
【发布时间】:2018-06-20 20:06:41
【问题描述】:

我有这两种型号:

// 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 时,我希望只返回一个 Event 而无需使用 Golang 逻辑执行清理。因为实际上,返回的文档有一个名为 event 的属性。我直接想要一个 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 应该可以帮助我做我想做的事情,但是我没有找到如何将嵌套文档转换为最终文档。

【问题讨论】:

    标签: mongodb go mgo


    【解决方案1】:

    您可以使用$unwindevent 数组字段“转换”为单个嵌入文档,然后使用$replaceRoot 将此event 字段“提升”为新的“根”:

    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 有多个事件,则此解决方案可以正确处理。

    【讨论】:

    • 太棒了!我不知道$replaceRoot,你的回答很完整,非常感谢。如果可以的话,请提出其他问题:关于索引有什么需要注意的以防止缓慢的请求吗? (因为 $lookup 和 $match)
    • @Elwyn 性能应该不错,只要确保你有正确的索引($match)。 $lookup 只是通过始终被索引的_id 查找。
    猜你喜欢
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多