更新值导致错误golang mongodb

fhity93d  于 2023-06-22  发布在  Go
关注(0)|答案(1)|浏览(135)

我试图更新我的mongo文档,但我一直得到一个错误,我似乎无法理解这个错误。

type UpdateCarpoolDTO struct {
    CarpoolID string    `json:"carpoolId" bson:"carpoolId"`
    Passenger Passenger `bson:"passenger" json:"passenger"`
}

type Passenger struct {
    User             User     `bson:"user" json:"user"`
    NumberOfSeats    int      `json:"numberOfSeats" bson:"numberOfSeats"`
    Pickup           Location `json:"pickup" bson:"pickup"`
    DropOff          Location `json:"dropOff" bson:"dropOff"`
    DoorToDoorOption bool     `bson:"doorToDoorOption" json:"doorToDoorOption"`
    LuggageSize      string   `bson:"luggageSize" json:"luggageSize"`
}

type Carpool struct {
    ID               string         `json:"id,omitempty" bson:"_id,omitempty"`
    SeatsAvailable   int            `json:"seatsAvailable" bson:"seatsAvailable"`
    Passengers       []*Passenger   `bson:"passengers" json:"passengers"`
    CreatedAt        time.Time      `json:"createdAt" bson:"createdAt"`
    UpdatedAt        time.Time      `json:"updatedAt" bson:"updatedAt"`
    ...
}

func (r *carpoolRepository) AddPassanger(dto *UpdateCarpoolDTO) (*Carpool, *errors.Error) {
    ctx, cancel := context.WithTimeout(context.Background(), mongoQueryTimeout)
    defer cancel()

    log.Println("THE DTO OBJ:::", dto)
    var result *Carpool
    filter := bson.M{"_id": dto.CarpoolID}

    update := bson.M{
        "$set": bson.M{
            "passangers": bson.M{
                "$push": dto.Passenger,
            },
            "seatsAvailable": bson.M{
                "$subtract": []interface{}{
                    "$seatsAvailable",
                    dto.Passenger.NumberOfSeats,
                },
            },
        },
        "$currentDate": bson.M{"updatedAt": true},
    }

    log.Println("THE DTO OBJ:::", "GOT HERE 1")
    options := options.FindOneAndUpdate().SetReturnDocument(1)
    log.Println("THE DTO OBJ:::", "GOT HERE 2")
    if err := r.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&result); err != nil {
        log.Println("THE DTO OBJ:::", "GOT HERE 3")
        if err == mongo.ErrNoDocuments {
            // failing here
            log.Println("THE DTO OBJ:::", "GOT HERE 4")
            return nil, errors.NewNotFoundError("request not found")
        }
        log.Println("THE DTO OBJ:::", "GOT HERE 5")
        log.Println("THE DTO OBJ 5 err:::", err.Error())
        return nil, errors.New(err.Error())
    }
    log.Println("THE DTO OBJ:::", "GOT HERE 6")
    return result, nil
}

我用来调试的log语句打印以下内容

THE DTO OBJ::: &{91e7a42c-xxxx {{Ebene  0x14000392c00 Obey 5120000000 <nil>} 1 {312 Main St 3 43.xxx -79.xxxx Ontario Toronto N2J 223 Canada <nil>} {978 Elm St 2 43.xxxx -80.xxx Ontario Toronto 2B2 111 Canada <nil>} true MEDIUM}} 2023/06/15 11:32:45  
THE DTO OBJ::: GOT HERE 1 2023/06/15 11:32:45  
THE DTO OBJ::: GOT HERE 2 2023/06/15 11:32:45  
THE DTO OBJ::: GOT HERE 3 2023/06/15 11:32:45  
THE DTO OBJ::: GOT HERE 5 2023/06/15 11:32:45  
THE DTO OBJ 5 err::: error decoding key seatsAvailable: cannot decode embedded document into an integer type

更多代码可根据要求提供。

ftf50wuq

ftf50wuq1#

我通过一个小例子展示了普通更新(使用FindOneAndUpdate方法完成)和使用Aggregate方法进行聚合操作之间的区别。作为一个前提,我通过从结构体中删除字段并硬编码一些值来简化代码。如果我错过了什么,只是让我知道,我会更新我的答案!
首先,让我们分享代码:

package main

import (
    "context"
    "fmt"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type Passenger struct {
    NumberOfSeats    int    `json:"numberOfSeats" bson:"numberOfSeats"`
    DoorToDoorOption bool   `bson:"doorToDoorOption" json:"doorToDoorOption"`
    LuggageSize      string `bson:"luggageSize" json:"luggageSize"`
}

type Carpool struct {
    ID             string       `json:"id,omitempty" bson:"_id,omitempty"`
    SeatsAvailable int          `json:"seatsAvailable" bson:"seatsAvailable"`
    Passengers     []*Passenger `bson:"passengers" json:"passengers"`
    CreatedAt      time.Time    `json:"createdAt" bson:"createdAt"`
    UpdatedAt      time.Time    `json:"updatedAt" bson:"updatedAt"`
}

func main() {
    clientOptions := options.Client().ApplyURI("mongodb://root:root@localhost:27017")
    mongoClient, err := mongo.Connect(context.Background(), clientOptions)
    if err != nil {
        panic(err)
    }
    defer mongoClient.Disconnect(context.Background())

    appDB := mongoClient.Database("appDB")
    demoCollection := appDB.Collection("demoCollection")

    // clean up data - troubleshooting purposes
    defer func() {
        demoCollection.DeleteMany(context.Background(), bson.M{})
    }()

    // seed data
    carPool := &Carpool{
        ID:             "1",
        SeatsAvailable: 4,
        Passengers: []*Passenger{
            {NumberOfSeats: 1, DoorToDoorOption: false, LuggageSize: "small"},
        },
        CreatedAt: time.Now(),
        UpdatedAt: time.Now(),
    }
    insertRes, err := demoCollection.InsertOne(context.Background(), carPool)
    if err != nil {
        panic(err)
    }

    // fetch data
    fmt.Println("before update")
    cursor, err := demoCollection.Find(context.Background(), bson.M{"_id": insertRes.InsertedID})
    if err != nil {
        panic(err)
    }
    var carPools []bson.M
    if err = cursor.All(context.Background(), &carPools); err != nil {
        panic(err)
    }
    for _, v := range carPools {
        fmt.Println(v)
    }

    // set data
    filter := bson.M{"_id": insertRes.InsertedID}
    update := bson.D{
        bson.E{
            Key: "$push",
            Value: bson.D{
                bson.E{
                    Key:   "passengers",
                    Value: &Passenger{NumberOfSeats: 2, DoorToDoorOption: true, LuggageSize: "medium"},
                },
            },
        },
    }
    updateOptions := options.FindOneAndUpdate().SetReturnDocument(1)
    demoCollection.FindOneAndUpdate(context.Background(), filter, update, updateOptions)

    // aggregate update
    pipe := []bson.M{
        {
            "$addFields": bson.M{ // if the field already exists, it overwrites the value
                "seatsAvailable": bson.M{
                    "$subtract": []string{"$seatsAvailable", "$seatsAvailable"},
                },
            },
        },
    }
    cursor, err = demoCollection.Aggregate(context.Background(), pipe)
    if err != nil {
        panic(err)
    }
    if err = cursor.All(context.Background(), &carPools); err != nil {
        panic(err)
    }
    fmt.Println("after update")
    for _, v := range carPools {
        fmt.Println(v)
    }
}

我将只对update和聚合函数进行更详细的介绍。

更新

更新功能分为以下几个部分:
1.设置用于获取要更新的文档的筛选器
1.设置$push运算符以向集合中添加项
1.设置要添加的值
这里没有什么要补充的。让我们切换到Aggregate函数。

聚合

对于此操作,您必须设置要使用的管道。此管道用于$addFiels阶段。
请注意,如果您要添加一个已经存在的字段,这将被覆盖。我选择用这个是因为我很好。
最后,必须设置要使用的运算符(在本例中为$subtract运算符),并提供一个字符串数组,表示要减去的数字。多亏了$subtract运算符,您可以从第一个中减去第二个。
我添加了一些日志用于演示目的。您可以很容易地看到记录被代码更新。
让我知道这是否有助于澄清您的问题,谢谢!

相关问题