Need help in getting an element from mongodb document and updating its value using go mongo drivers

huangapple go评论68阅读模式
英文:

Need help in getting an element from mongodb document and updating its value using go mongo drivers

问题

嗨,根据你的描述,你的代码中的函数返回“未找到文档”的原因可能是过滤条件不匹配任何文档。你的函数ChangeDefaultPack的目的是将与给定ID和贴纸类型匹配的贴纸包的默认值设置为false,并将作为参数传递给函数的贴纸包的默认值设置为true

在你的代码中,过滤条件是根据useridstickernameformat来构建的。请确保这些值在数据库中存在,并且与要更新的文档匹配。你可以通过打印过滤条件和查询结果来调试代码,以确定是否存在匹配的文档。

另外,请确保你的数据库连接已正确设置,并且你有适当的权限来执行更新操作。如果连接或权限有问题,可能会导致函数返回错误或未找到文档。

希望这些信息对你有帮助!如果你有任何其他问题,请随时提问。

英文:

Hey there I am using the go.mongodb.org/mongo-driver package to work with golang. This is my code:

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
}

And this is the db structure:

...
{
"_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
}
...

What I need my code is to find list of sticker packs which matches the given id and sticker type and set their default value to false and set the default value of the pack which is passed to the func as true.

Basically just making one as default and others as not default. Could someone explain me why this function is returning no document found?

答案1

得分: 0

当存在多个字段匹配时,您应该使用$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",
英文:

When there are multiple field matches, you should use the $elemMatch operator. Otherwise, the $ operator does not work. See Update Embedded Documents Using Multiple Field Matches.

And you don't need UpdateMany to update multiple array elements in a single document. Use UpdateOne instead.

Here is the demo based on your code and data:

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)
	}
}

Run the demo and you will observe the following change to the document:

--- 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",

huangapple
  • 本文由 发表于 2023年6月26日 22:35:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557686.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定