如何返回ID为

时间:2018-04-03 13:08:49

标签: mongodb go mgo

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

Mongo example document

我想要做的是(从实际代码中可以看到)更新role中的members.x.role字段,其中members.x.id等于给定ID(ID为UUID,因此它&# 39; s唯一;这部分代码没有问题)然后我想返回members.x。但问题是它总是返回第一个成员而不是刚刚更新的成员。我已经尝试了一些 mgo 的方法,发现Distinct()最接近我的期望,但这并不是我想要的。

我的问题是如何以指定的ID返回member 嵌入式文档

我已经查看了thisthis,但它对我没有帮助。

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
}

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方法,它不是严格的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")
}