英文:
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,
},
},
},
},
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论