使用数组过滤器更新不会更新任何内容 mongo go driver

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

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

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

{"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":[]}}

我们可以清楚地看到 mathedCount 为 1,modifiedCount 为 0。

有什么想法吗?我基于这个文档:https://www.mongodb.com/docs/drivers/go/current/fundamentals/crud/write-operations/embedded-arrays/

我犯的错误是因为我重复了过滤器名称。而不是:

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

我应该使用:

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