如何 return 嵌入 ID 为

How to return embedded document with ID of

我有一个 MongoDB 集合,其中包含如下示例文档:

我想做的(正如你从实际代码中看到的那样)是更新 members.x.role 中的一个 role 字段,其中 members.x.id 等于给定的 ID(ID 是 UUID 所以它是独一无二的;这部分代码可以正常工作)然后我想 return 那 members.x。但问题是它总是 return 的第一个成员,而不是刚刚更新的那个。我已经尝试了 mgo 的一些方法,发现 Distinct() 最接近我的期望,但这并不像我想要的那样有效。

我的问题是如何return member 嵌入文档 指定ID?

我已经看过 this and 但它对我没有帮助。

func (r MongoRepository) UpdateMemberRole(id string, role int8) (*Member, error) {
    memberQuery := &bson.M{"members": &bson.M{"$elemMatch": &bson.M{"id": id}}}
    change := &bson.M{"members.$.role": role}

    err := r.db.C("groups").Update(memberQuery, &bson.M{"$set": &change})
    if err == mgo.ErrNotFound {
        return nil, fmt.Errorf("member with ID '%s' does not exist", id)
    }

    // FIXME: Retrieve this member from query below. THIS ALWAYS RETURNS FIRST MEMBER!!!
    var member []Member
    r.db.C("groups").Find(&bson.M{"members.id": id}).Distinct("members.0", &member)

    return &member[0], nil
}

我找到了一个解决方法,它不是严格的 Mongo 返回此嵌入文档的查询,但在我看来,这段代码比一些无论如何都获取整个文档的奇特 Mongo 查询更清晰易懂。

func (r MongoRepository) UpdateMemberRole(id string, role int8) (*Member, error) {
    change := mgo.Change{
        Update: bson.M{"$set": bson.M{"members.$.role": role}},
        ReturnNew: true,
    }

    var updatedGroup Group
    _, err := r.db.C("groups").Find(bson.M{"members": bson.M{"$elemMatch": bson.M{"id": id}}}).Apply(change, &updatedGroup)
    if err == mgo.ErrNotFound {
        return nil, fmt.Errorf("member with ID '%s' does not exist", id)
    } else if err != nil {
        return nil, err
    }

    for _, member := range updatedGroup.Members {
        if member.Id == id {
            return &member, nil
        }
    }

    return nil, fmt.Errorf("weird error, Id cannot be found")
}