如何使用mongo-go-driver的update函数

ryoqjall  于 2023-05-04  发布在  Go
关注(0)|答案(4)|浏览(111)

mongo-go-driver的update函数可以这样调用。

filter := bson.D{"username", username}
update := bson.D{{"$set",
    bson.D{
        {"name", person.Name},
    },
}}
result, err := collection.UpdateOne(ctx, filter, update)
type Person struct {
    ID       primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
    Username string             `json:"username,omitempty" bson:"username,omitempty"`
    Name     string             `json:"name,omitempty" bson:"name,omitempty"`
}

但是,我需要使用person结构调用update函数,而不像这样提及person结构的每个字段。

filter := bson.D{"username", username}
update := bson.D{{"$set", <<how to convert person struct to bson document?>>}}
result, err := collection.UpdateOne(ctx, filter, update)

如何将person结构转换为bson文档?

q5iwbnjs

q5iwbnjs1#

ReplaceOne我想这是你要找的:

// Use it's ID to replace
        filter := bson.M{"_id": existing.ID}
        // Create a replacement object using the existing object
        replacementObj := existing
        replacementObj.SomeFieldToChange = "new-replacement-object"
        updateResult, err := coll.ReplaceOne(context.Background(), filter, replacementObj)
        assertNotErr(t, err)
        assertEquals(t, 1, int(updateResult.ModifiedCount))

注意ErrNotFound不再像在mgo中那样抛出-您必须检查Modified/Upserted计数。

pprl5pva

pprl5pva2#

你可以这样做:

func Update(person Person) error {
  pByte, err := bson.Marshal(person)
  if err != nil {
    return err
  }

  var update bson.M
  err = bson.Unmarshal(pByte, &update)
  if err != nil {
    return
  }

  // NOTE: filter and ctx(Context) should be already defined
  _, err = collection.UpdateOne(ctx, filter, bson.D{{Key: "$set", Value: update}})
  if err != nil {
    return err
  }
  return nil
}
csga3l58

csga3l583#

如何将person结构编组到bson?

package main

import (
        "fmt"

        "labix.org/v2/mgo/bson"
)

type person struct {
        ID       string `json:"_id,omitempty" bson:"_id,omitempty"`
        Username string `json:"username,omitempty" bson:"username,omitempty"`
        Name     string `json:"name,omitempty" bson:"name,omitempty"`
}

func main() {
        p := person{
                ID:       "id",
                Username: "uname",
                Name:     "name",
        }
        var (
                bm  []byte
                err error
        )
        if bm, err = bson.Marshal(p); err != nil {
                panic(fmt.Errorf("can't marshal:%s", err))
        }
        update := bson.D{{"$set", bm}}
        fmt.Printf("update is:%q\n", update)
}

运行:

./sobson
update is:[{"$set" "4\x00\x00\x00\x02_id\x00\x03\x00\x00\x00id\x00\x02username\x00\x06\x00\x00\x00uname\x00\x02name\x00\x05\x00\x00\x00name\x00\x00"}]
kkih6yb8

kkih6yb84#

我想提出一个更直接的方法,涉及一些样板,但结果是一个准确和可扩展的代码。

// define consts for column names to avoid typos
const (
    ColPersonUsername = "username"
    ColPersonName     = "name"
)

type Person struct {
    ID       primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
    Username string             `json:"username,omitempty" bson:"username,omitempty"`
    Name     string             `json:"name,omitempty" bson:"name,omitempty"`
}

// create helper methods and functions for BSON generation 
func (p Person) encodeBSON() interface{} {
    return bson.M{
        ColPersonUsername: p.Username,
        ColPersonName:     p.Name,
    }
}

func filterByID(id interface{}) interface{} {
    return bson.M{
        "_id": id,
    }
}

那么update函数可以是这样的:

func (s *Store) UpdatePerson(ctx context.Context, person Person) error {
    _, err := s.collection.UpdateOne(ctx, 
        filterByID(person.ID), 
        bson.M{"$set": person.encodeBSON()})
    if err != nil {
        return err
    }
    return nil
}

相关问题