【问题标题】:How can I convert updateMany with ArrayFilters options mongodb query into Golang?如何将带有 ArrayFilters 选项的 updateMany mongodb 查询转换为 Golang?
【发布时间】:2023-02-15 22:13:54
【问题描述】:

我在为 mongodb 查询编写 golang 代码时遇到问题。我曾尝试转换以下 mongodb 查询:

db.batches.updateMany(
         {"batchedOrders.newOrderObject.orderDetails.trackingId" :  "ORDER_JEET_2023_02_05_01"},
         { $set: { "batchedOrders.$[elem].newOrderObject.pickupDetails.note" : "Welcome" } },
         { arrayFilters: [ { "elem.newOrderObject.orderDetails.trackingId": "ORDER_JEET_2023_02_05_01" } ] }
      )

高朗代码:

这里 b 是 interface{} 并携带以下数据:

{
    "batchedOrders.$[elem].newOrderObject.dropoffDetails.recipientDetails.email": "das@rara.delivery",
    "batchedOrders.$[elem].newOrderObject.orderDetails.dimensions.height": 0,
    "batchedOrders.$[elem].newOrderObject.orderDetails.dimensions.length": 0,
    "batchedOrders.$[elem].newOrderObject.orderDetails.dimensions.unit": "cm",
    "batchedOrders.$[elem].newOrderObject.orderDetails.dimensions.width": 0,
    "batchedOrders.$[elem].newOrderObject.orderDetails.orderDeliveryDetails.sla.dropoff": 1675712794,
    "batchedOrders.$[elem].newOrderObject.orderDetails.parcelSize": "Medium",
    "batchedOrders.$[elem].newOrderObject.orderDetails.weightDetails.billableWeight": 5,
    "batchedOrders.$[elem].newOrderObject.orderDetails.weightDetails.volWeight": 5,
    "batchedOrders.$[elem].newOrderObject.orderDetails.weightDetails.weight": 5,
    "batchedOrders.$[elem].newOrderObject.orderDetails.weightIndex": 1,
    "batchedOrders.$[elem].newOrderObject.pickupDetails.pickupIncharge.name": "Mukesh"
}

以下是 golang 代码:

data, _ := bson.Marshal(b)

    err = bson.Unmarshal([]byte(data), &doc)

    arrayFilters := options.ArrayFilters{Filters: []interface{}{bson.D{
        {Key: "elem.newOrderObject.orderDetails.trackingId", Value: trackingId},
    }}}

    opts := options.UpdateOptions{
        ArrayFilters: &arrayFilters,
    }

    res, err := db.Collection(BATCH_COLLECTION_NAME).UpdateMany(ctx, bson.D{{Key: "batchedOrders.newOrderObject.orderDetails.trackingId", Value: trackingId}}, bson.M{"$set": doc}, &opts)
    if err != nil {
        log.Println(lg.Info(err))
        return false, err
    }

我收到以下错误:

WriteString can only write while positioned on a Element or Value but is positioned on a TopLevel

我正在尝试更新 mongodb 数据库中的多个数据。但是出现错误。

【问题讨论】:

    标签: mongodb go


    【解决方案1】:

    为了成功使用UpdateMany方法,你应该做类似这样的事情:

    package main
    
    import (
        "context"
        "fmt"
        "strings"
        "time"
    
        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
    )
    
    var (
        ctx    context.Context
        cancel context.CancelFunc
    )
    
    type Message struct {
        ID   string `json:"id" bson:"id"`
        Name string `json:"name" bson:"name"`
    }
    
    func main() {
        ctx, cancel = context.WithTimeout(context.Background(), 20*time.Second)
        defer cancel()
    
        // set MongoDB connection
        clientOptions := options.Client().ApplyURI("mongodb://root:root@localhost:27017")
        mongoClient, err := mongo.Connect(ctx, clientOptions)
        if err != nil {
            panic(err)
        }
        defer mongoClient.Disconnect(ctx)
    
        // select collection
        collection := mongoClient.Database("demodb").Collection("myCollection")
        defer collection.Drop(ctx)
    
        fmt.Println("original documents")
        // insert some random msg
        if _, err := collection.InsertMany(ctx, []interface{}{
            Message{"1", "John Doe"},
            Message{"2", "Suzy Lee"},
            Message{"3", "John Doe"},
        }); err != nil {
            panic(err)
        }
    
        // get records
        var messagesTmp []bson.M
        cursorTmp, err := collection.Find(ctx, bson.M{})
        if err != nil {
            panic(err)
        }
    
        if err := cursorTmp.All(ctx, &messagesTmp); err != nil {
            panic(err)
        }
    
        for _, v := range messagesTmp {
            fmt.Println(v)
        }
        fmt.Println(strings.Repeat("#", 100))
    
        // update
        var updateRes *mongo.UpdateResult
        if updateRes, err = collection.UpdateMany(ctx,
            bson.M{"name": "John Doe"},
            bson.D{
                bson.E{
                    Key: "$set",
                    Value: bson.D{
                        bson.E{
                            Key:   "name",
                            Value: "John Doe - Edited",
                        },
                    },
                },
            },
        ); err != nil {
            panic(err)
        }
        fmt.Println("num docs updated:", updateRes.ModifiedCount)
    
        // list all
        fmt.Println(strings.Repeat("#", 100))
        fmt.Println("new documents")
        var messages []Message
        cursor, err := collection.Find(ctx, bson.M{})
        if err != nil {
            panic(err)
        }
    
        if err := cursor.All(ctx, &messages); err != nil {
            panic(err)
        }
    
        for _, v := range messages {
            fmt.Println(v)
        }
    }
    

    在这里,相关部分是 // update 部分。首先,我们构建将用于获取要更新的文档的过滤条件。然后,我们给$set一个字段name指定一个特定的值John Doe - Edited

    其余代码用于构建一个简单的程序,以证明实际更改正在起作用。请随意根据您的规格调整我的示例代码,让我知道是否也适合您!

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 2011-05-23
      • 2018-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      相关资源
      最近更新 更多