使用数组过滤器进行更新,在MongoDB Go驱动程序中没有更新任何内容。

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

Update with array filter doesn't update anything mongo go driver

问题

我有以下函数:

func AuthorizeClasses(teacherId primitive.ObjectID, classesNames []string) error {
	if res := usersCollection.FindOneAndUpdate(
		context.TODO(),
		bson.M{
			"_id": teacherId,
		},
		bson.M{
			"$set": bson.M{
				"teachersettings.classes.$[elem].authorized": true,
			},
		},
		options.FindOneAndUpdate().SetArrayFilters(
			options.ArrayFilters{
				Filters: []interface{}{
					bson.M{
						"elem": bson.M{
							"elem.name": bson.M{
								"$in": classesNames,
							},
						},
					},
				},
			},
		),
	); res.Err() != nil {
		return res.Err()
	}
	return nil
}

它应该将authorized字段设置为true,对于所有名称在函数参数中的切片中的类。

这是我处理的文档示例:

{
   "_id":{
      "$oid":"625a68ef7cda954a2c60a28b"
   },
   "email":"test@gmail.com",
   "username":"test",
   "password":"40b52e5d6c2d00f632d4b2adb13ed9e90c007619701dee7757124d411e0e8ada",
   "salt":"xksV2aFlihZHlFE",
   "isteacher":true,
   "teachersettings":{
      "schedule":null,
      "classes":[
         {
            "name":"wxipsbkuqyrfhir",
            "authorized":false,
            "students":[
               {
                  "email":"eqfvgvazsrpimtx@ajmje.gmg",
                  "username":"yehfmvpjuf",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e2"
                  }
               },
               {
                  "email":"wmhkuhnbrslrlcb@pqdaw.rmo",
                  "username":"xkylcaotxn",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e3"
                  }
               },
               {
                  "email":"wsnlgxzmuwjjwow@ziwxh.gsj",
                  "username":"bnazhckxqe",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e4"
                  }
               }
            ]
         },
         {
            "name":"rcoelwwhfjilqzo",
            "authorized":false,
            "students":[
               {
                  "email":"eqfvgvazsrpimtx@ajmje.gmg",
                  "username":"yehfmvpjuf",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e2"
                  }
               },
               {
                  "email":"wmhkuhnbrslrlcb@pqdaw.rmo",
                  "username":"xkylcaotxn",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e3"
                  }
               },
               {
                  "email":"wsnlgxzmuwjjwow@ziwxh.gsj",
                  "username":"bnazhckxqe",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e4"
                  }
               }
            ]
         }
      ]
   }
}

例如,如果我这样调用函数:

AuthorizeClasses(teacher.Id, []string{"wxipsbkuqyrfhir", "rcoelwwhfjilqzo"})

我期望两个相应的authorized字段切换为true

问题是该函数从不更新任何内容。结果的错误属性也为空。

这是与此操作相关的日志序列:

{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"I",  "c":"WRITE",    "id":51803,   "ctx":"conn56","msg":"Slow query","attr":{"type":"update","ns":"MYPROJECT.users","command":{"q":{"_id":{"$oid":"626d626a355c74c07681428b"}},"u":{"$set":{"teachersettings.classes.$[elem].authorized":true}},"arrayFilters":[{"elem":{"elem.name":{"$in":["bvzhahfllofihjh"]}}}],"multi":false,"upsert":false},"planSummary":"IDHACK","keysExamined":1,"docsExamined":1,"nMatched":1,"nModified":0,"nUpserted":0,"numYields":0,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":1}}},"flowControl":{"acquireCount":1,"timeAcquiringMicros":1},"storage":{},"remote":"127.0.0.1:63557","durationMillis":0}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"D2", "c":"REPL",     "id":22549,   "ctx":"conn56","msg":"Waiting for write concern. OpTime: {replOpTime}, write concern: {writeConcern}","attr":{"replOpTime":{"ts":{"$timestamp":{"t":0,"i":0}}},"writeConcern":{"w":1,"wtimeout":0,"provenance":"implicitDefault"}}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"I",  "c":"COMMAND",  "id":51803,   "ctx":"conn56","msg":"Slow query","attr":{"type":"command","ns":"MYPROJECT.$cmd","command":{"update":"users","ordered":true,"lsid":{"id":{"$uuid":"92834e13-e3cc-4938-944a-2ce19f578b39"}},"$db":"MYPROJECT"},"numYields":0,"reslen":60,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":1}},"ReplicationStateTransition":{"acquireCount":{"w":2}},"Global":{"acquireCount":{"r":1,"w":1}},"Database":{"acquireCount":{"w":1}},"Collection":{"acquireCount":{"w":1}},"Mutex":{"acquireCount":{"r":1}}},"flowControl":{"acquireCount":1,"timeAcquiringMicros":1},"storage":{},"remote":"127.0.0.1:63557","protocol":"op_msg","durationMillis":0}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"D2", "c":"QUERY",    "id":22783,   "ctx":"conn56","msg":"Received interrupt request for unknown op","attr":{"opId":23521,"knownOps":[]}}

我们可以清楚地看到匹配计数为1,修改计数为0。

有什么想法吗?我根据这个文档进行了操作:https://www.mongodb.com/docs/drivers/go/current/fundamentals/crud/write-operations/embedded-arrays/

英文:

I have the following function :

func AuthorizeClasses(teacherId primitive.ObjectID, classesNames []string) error {
	if res := usersCollection.FindOneAndUpdate(
		context.TODO(),
		bson.M{
			"_id": teacherId,
		},
		bson.M{
			"$set": bson.M{
				"teachersettings.classes.$[elem].authorized": true,
			},
		},
		options.FindOneAndUpdate().SetArrayFilters(
			options.ArrayFilters{
				Filters: []interface{}{
					bson.M{
						"elem": bson.M{
							"elem.name": bson.M{
								"$in": classesNames,
							},
						},
					},
				},
			},
		),
	); res.Err() != nil {
		return res.Err()
	}
	return nil
}

It is supposed to set the authorized field to true on all the classes whose name is in the slice that's an argument to the function.

Here is an example of the documents I'm dealing with :

{
   "_id":{
      "$oid":"625a68ef7cda954a2c60a28b"
   },
   "email":"test@gmail.com",
   "username":"test",
   "password":"40b52e5d6c2d00f632d4b2adb13ed9e90c007619701dee7757124d411e0e8ada",
   "salt":"xksV2aFlihZHlFE",
   "isteacher":true,
   "teachersettings":{
      "schedule":null,
      "classes":[
         {
            "name":"wxipsbkuqyrfhir",
            "authorized":false,
            "students":[
               {
                  "email":"eqfvgvazsrpimtx@ajmje.gmg",
                  "username":"yehfmvpjuf",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e2"
                  }
               },
               {
                  "email":"wmhkuhnbrslrlcb@pqdaw.rmo",
                  "username":"xkylcaotxn",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e3"
                  }
               },
               {
                  "email":"wsnlgxzmuwjjwow@ziwxh.gsj",
                  "username":"bnazhckxqe",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e4"
                  }
               }
            ]
         },
         {
            "name":"rcoelwwhfjilqzo",
            "authorized":false,
            "students":[
               {
                  "email":"eqfvgvazsrpimtx@ajmje.gmg",
                  "username":"yehfmvpjuf",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e2"
                  }
               },
               {
                  "email":"wmhkuhnbrslrlcb@pqdaw.rmo",
                  "username":"xkylcaotxn",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e3"
                  }
               },
               {
                  "email":"wsnlgxzmuwjjwow@ziwxh.gsj",
                  "username":"bnazhckxqe",
                  "id":{
                     "$oid":"626ac9ddd6806cb8838898e4"
                  }
               }
            ]
         }
      ]
   }
}

For example, if i called the function like this :

AuthorizeClasses(teacher.Id, []string{"wxipsbkuqyrfhir", "rcoelwwhfjilqzo"})

I would expect the two corresponding authorized fields to switch to true.

The problem is the function doesn't ever update anything. The error attribute of the result is also empty.

Here is the log sequence associated to this operation :

{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"I",  "c":"WRITE",    "id":51803,   "ctx":"conn56","msg":"Slow query","attr":{"type":"update","ns":"MYPROJECT.users","command":{"q":{"_id":{"$oid":"626d626a355c74c07681428b"}},"u":{"$set":{"teachersettings.classes.$[elem].authorized":true}},"arrayFilters":[{"elem":{"elem.name":{"$in":["bvzhahfllofihjh"]}}}],"multi":false,"upsert":false},"planSummary":"IDHACK","keysExamined":1,"docsExamined":1,"nMatched":1,"nModified":0,"nUpserted":0,"numYields":0,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":1}},"ReplicationStateTransition":{"acquireCount":{"w":1}},"Global":{"acquireCount":{"w":1}},"Database":{"acquireCount":{"w":1}},"Collection":{"acquireCount":{"w":1}},"Mutex":{"acquireCount":{"r":1}}},"flowControl":{"acquireCount":1,"timeAcquiringMicros":1},"storage":{},"remote":"127.0.0.1:63557","durationMillis":0}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"D2", "c":"REPL",     "id":22549,   "ctx":"conn56","msg":"Waiting for write concern. OpTime: {replOpTime}, write concern: {writeConcern}","attr":{"replOpTime":{"ts":{"$timestamp":{"t":0,"i":0}},"t":-1},"writeConcern":{"w":1,"wtimeout":0,"provenance":"implicitDefault"}}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"I",  "c":"COMMAND",  "id":51803,   "ctx":"conn56","msg":"Slow query","attr":{"type":"command","ns":"MYPROJECT.$cmd","command":{"update":"users","ordered":true,"lsid":{"id":{"$uuid":"92834e13-e3cc-4938-944a-2ce19f578b39"}},"$db":"MYPROJECT"},"numYields":0,"reslen":60,"locks":{"ParallelBatchWriterMode":{"acquireCount":{"r":1}},"ReplicationStateTransition":{"acquireCount":{"w":2}},"Global":{"acquireCount":{"r":1,"w":1}},"Database":{"acquireCount":{"w":1}},"Collection":{"acquireCount":{"w":1}},"Mutex":{"acquireCount":{"r":1}}},"flowControl":{"acquireCount":1,"timeAcquiringMicros":1},"storage":{},"remote":"127.0.0.1:63557","protocol":"op_msg","durationMillis":0}}
{"t":{"$date":"2022-04-30T19:43:07.596+03:00"},"s":"D2", "c":"QUERY",    "id":22783,   "ctx":"conn56","msg":"Received interrupt request for unknown op","attr":{"opId":23521,"knownOps":[]}}

We can clearly see the mathedCount at 1 and the modifiedCount at 0.

Any ideas ? I based myself on this doc : https://www.mongodb.com/docs/drivers/go/current/fundamentals/crud/write-operations/embedded-arrays/

答案1

得分: 1

我犯的错误是因为我重复了过滤器名称。应该使用以下代码:

opt := options.FindOneAndUpdate().SetArrayFilters(
            options.ArrayFilters{
                Filters: []interface{}{
                    bson.M{
                        "elem.name": bson.M{
                            "$in": classesNames,
                        },
                    },
                },
            },
        )
英文:

The mistake I made came from the fact I was repeating the filter name. Instead of :

opt := options.FindOneAndUpdate().SetArrayFilters(
            options.ArrayFilters{
                Filters: []interface{}{
                    bson.M{
                        "elem": bson.M{
                            "elem.name": bson.M{
                                "$in": classesNames,
                            },
                        },
                    },
                },
            },
        )

I should use :

opt := options.FindOneAndUpdate().SetArrayFilters(
            options.ArrayFilters{
                Filters: []interface{}{
                    bson.M{
                        "elem.name": bson.M{
                             "$in": classesNames,
                        },
                    },
                },
            },
        )

huangapple
  • 本文由 发表于 2022年4月30日 20:58:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/72068725.html
匿名

发表评论

匿名网友

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

确定