需要帮助从mongodb文档中获取元素并使用go mongo驱动程序更新其值

plicqrtu  于 2023-06-27  发布在  Go
关注(0)|答案(1)|浏览(180)

嘿,我正在使用go.mongodb.org/mongo-driver包与golang一起工作。这是我的代码:

package src

import (
    "context"
    "fmt"
    "log"

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

var (
    client      *mongo.Client
    stickerscol *mongo.Collection
)

func init() {
    log.Println("Setting up database...")
    var err error
    client, err = mongo.Connect(context.Background(), options.Client().ApplyURI(Envars.DbUrl))
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Connected to database")
    stickerscol = client.Database("stickersbot").Collection("stickers")
    chatcol = client.Database("stickersbot").Collection("chat")
}

func ChangeDefaultPack(userid int64, stickername string, format string) error {
    fmt.Println(userid, stickername, format)
    filter := bson.M{
        "_id":                      userid,
        "stickers.stickername":     stickername,
        "stickers.stickerpacktype": format,
    }
    updateOther := bson.M{
        "$set": bson.M{
            "stickers.$[elem].isdefault": false,
        },
    }
    update := bson.M{
        "$set": bson.M{
            "stickers.$.isdefault": true,
        },
    }
    arrayFilters := options.ArrayFilters{
        Filters: []interface{}{bson.M{"elem.stickerpacktype": format}},
    }
    updateOptions := options.Update().SetArrayFilters(arrayFilters)
    _, err := stickerscol.UpdateMany(context.TODO(), filter, updateOther, updateOptions)
    if err != nil {
        return err
    }
    ok, err := stickerscol.UpdateOne(context.Background(), filter, update, options.Update().SetUpsert(true))
    if err != nil {
        return err
    }
    if ok.ModifiedCount == 0 {
        fmt.Println("no document matched")
        return fmt.Errorf("no document matched")
    }
    return err
}

这就是db结构:

...
{
  "_id": 1633375527,
  "stickers": [
    {
      "stickerpacktype": "static",
      "stickername": "gVtOy_1633375527_by_ChadManBot",
      "isdefault": true
    },
    {
      "stickerpacktype": "animated",
      "stickername": "zIjsa_1633375527_by_ChadManBot",
      "isdefault": true
    },
    {
      "stickerpacktype": "video",
      "stickername": "bJBle_1633375527_by_ChadManBot",
      "isdefault": true
    },
    {
      "stickerpacktype": "static",
      "stickername": "iujiw_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "video",
      "stickername": "CHnqb_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "XKJUP_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "animated",
      "stickername": "pCFlC_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "animated",
      "stickername": "jGGgt_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "animated",
      "stickername": "cTxyA_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "animated",
      "stickername": "ZfYXO_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "xJUkA_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "HIvsY_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "WIHFQ_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "OqjtE_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "QNysO_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "OrTsT_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "FzROg_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "QUBcT_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "NsZfM_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "AkxVM_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "Ddvus_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "LXfHV_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "sTaMv_1633375527_by_ChadManBot",
      "isdefault": false
    },
    {
      "stickerpacktype": "static",
      "stickername": "vppgK_1633375527_by_ChadManBot",
      "isdefault": false
    }
  ],
  "stickerpackcount": 2
}
...

我需要的代码是找到与给定ID和贴纸类型匹配的贴纸包列表,并将其默认值设置为false,并将传递给func的包的默认值设置为true
基本上就是把一个设为默认值,其他的不设为默认值。有人能解释一下为什么这个函数没有返回文档吗?

qmelpv7a

qmelpv7a1#

当有多个字段匹配时,应该使用$elemMatch运算符。否则,$运算符不起作用。请参阅使用多个字段匹配更新嵌入文档。
而且您不需要UpdateMany来更新单个文档中的多个数组元素。使用UpdateOne代替。
以下是基于您的代码和数据的演示:

package main

import (
    "context"
    "fmt"
    "log"

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

var (
    client      *mongo.Client
    stickerscol *mongo.Collection
)

func init() {
    log.Println("Setting up database...")
    var err error
    client, err = mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost"))
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Connected to database")
    stickerscol = client.Database("stickersbot").Collection("stickers")
}

func ChangeDefaultPack(userid int64, stickername string, format string) error {
    fmt.Println(userid, stickername, format)
    filter := bson.M{
        "_id": userid,
        "stickers": bson.M{
            "$elemMatch": bson.M{
                "stickername":     stickername,
                "stickerpacktype": format,
            },
        },
    }
    updateOther := bson.M{
        "$set": bson.M{
            "stickers.$[elem].isdefault": false,
        },
    }
    arrayFilters := options.ArrayFilters{
        Filters: []interface{}{bson.M{"elem.stickerpacktype": format}},
    }
    updateOptions := options.Update().SetArrayFilters(arrayFilters)
    result, err := stickerscol.UpdateOne(context.Background(), filter, updateOther, updateOptions)
    if err != nil {
        return err
    }
    log.Printf("update other: %+v\n", result)

    update := bson.M{
        "$set": bson.M{
            "stickers.$.isdefault": true,
        },
    }
    ok, err := stickerscol.UpdateOne(context.Background(), filter, update, options.Update().SetUpsert(true))
    if err != nil {
        return err
    }
    log.Printf("update default: %+v\n", ok)
    if ok.ModifiedCount == 0 {
        fmt.Println("no document matched")
        return fmt.Errorf("no document matched")
    }
    return err
}

func main() {
    if err := ChangeDefaultPack(1633375527, "Ddvus_1633375527_by_ChadManBot", "static"); err != nil {
        panic(err)
    }
}

运行演示,您将观察到文档的以下更改:

--- before.json 2023-06-27 00:34:32.721978745 +0800
+++ after.json  2023-06-27 00:34:59.489836137 +0800
@@ -4,7 +4,7 @@
     {
       "stickerpacktype": "static",
       "stickername": "gVtOy_1633375527_by_ChadManBot",
-      "isdefault": true
+      "isdefault": false
     },
     {
       "stickerpacktype": "animated",
@@ -104,7 +104,7 @@
     {
       "stickerpacktype": "static",
       "stickername": "Ddvus_1633375527_by_ChadManBot",
-      "isdefault": false
+      "isdefault": true
     },
     {
       "stickerpacktype": "static",

相关问题