Mongodb 使用数组过滤器更新 |写入异常:写入错误:[无法将数组更新应用于非数组元素组:null]
Mongodb update with arrayfilters | write exception: write errors: [Cannot apply array updates to non-array element groups: null]
我有以下 employee
数据结构:
{
"_id":{
"$oid":"62836b0b3c1e2c19eaaac07e"
},
"firstname":"jean",
"lastname":"paul",
"email":"employee@test.co",
"password":"d94307e0eabb9bba1ea1291e4b043175e11dcc43875a4858690e5c236b989f3e",
"salt":"2CzpCiIbiyYcSxQ",
"organizations":[
{
"organizationid":{
"$oid":"62836aa93c1e2c19eaaac07d"
},
"organizationname":"test",
"ismanager":false,
"groups":[
{
"name":"mongroupe",
"permissions":[
0,
2
]
}
],
"permissions":[
1
]
}
]
}
我正在尝试在 go 中构建一个向 organizations.[x].groups.[x].permissions
数组添加一组权限的函数。每个 permission
都是一个简单的整数。
我想出了以下代码:
func AddPermissionsToGroup(groupName string, organizationId primitive.ObjectID, permissions []global.Permission) error {
if res, err := employeesCollection.UpdateMany(
context.TODO(),
bson.M{},
bson.M{
"$addToSet": bson.M{
"organizations.$[org].groups.$[grp].permissions": bson.M{
"$each": permissions,
},
},
},
options.Update().SetArrayFilters(
options.ArrayFilters{
Filters: []interface{}{
bson.M{
"org.organizationid": organizationId,
},
bson.M{
"grp.name": groupName,
},
},
},
),
); res.MatchedCount == 0 {
return global.ErrEntityNotFound
} else if res.ModifiedCount == 0 {
return global.ErrNoUpdateNeeded
} else if err != nil {
return fmt.Errorf("failed updating employees | %s", err.Error())
}
return nil
}
代码returns出现以下错误:写入异常:写入错误:[无法将数组更新应用于非数组元素组:空]。
我不知道这是什么意思。
也许引擎不喜欢我使用两个 ArrayFilter
的事实?
好的,所以我创建了这个有效的游乐场:https://mongoplayground.net/p/Tznz7btfLkH
实际上问题不是因为请求本身在语法上是有效的。这是因为我在 employee
集合中有另一个文档,看起来像这样:
{
"_id":{
"$oid":"62836aa93c1e2c19eaaac07c"
},
"firstname":"jean",
"lastname":"charles",
"email":"manager@test.co",
"password":"6776c354fce809e7be234f84d0ea907cfd3aba350871a18858ceccc10eabc036",
"salt":"IHaPJIKVVplC8ni",
"organizations":[
{
"organizationid":{
"$oid":"62836aa93c1e2c19eaaac07d"
},
"organizationname":"test",
"ismanager":true,
"groups":null,
"permissions":null
}
]
}
如您所见,此处的 groups
值为空。这就是问题所在。
基本上,当名为 grp
的数组过滤器遇到一个空对象时,它会引发一个错误,因为它不能应用于它。
因此,使请求有效的解决方案是确保集合中的每个文档都初始化了这个 group
数组(即使它是空的,也没关系)。一旦我这样做就没有问题了。
我有以下 employee
数据结构:
{
"_id":{
"$oid":"62836b0b3c1e2c19eaaac07e"
},
"firstname":"jean",
"lastname":"paul",
"email":"employee@test.co",
"password":"d94307e0eabb9bba1ea1291e4b043175e11dcc43875a4858690e5c236b989f3e",
"salt":"2CzpCiIbiyYcSxQ",
"organizations":[
{
"organizationid":{
"$oid":"62836aa93c1e2c19eaaac07d"
},
"organizationname":"test",
"ismanager":false,
"groups":[
{
"name":"mongroupe",
"permissions":[
0,
2
]
}
],
"permissions":[
1
]
}
]
}
我正在尝试在 go 中构建一个向 organizations.[x].groups.[x].permissions
数组添加一组权限的函数。每个 permission
都是一个简单的整数。
我想出了以下代码:
func AddPermissionsToGroup(groupName string, organizationId primitive.ObjectID, permissions []global.Permission) error {
if res, err := employeesCollection.UpdateMany(
context.TODO(),
bson.M{},
bson.M{
"$addToSet": bson.M{
"organizations.$[org].groups.$[grp].permissions": bson.M{
"$each": permissions,
},
},
},
options.Update().SetArrayFilters(
options.ArrayFilters{
Filters: []interface{}{
bson.M{
"org.organizationid": organizationId,
},
bson.M{
"grp.name": groupName,
},
},
},
),
); res.MatchedCount == 0 {
return global.ErrEntityNotFound
} else if res.ModifiedCount == 0 {
return global.ErrNoUpdateNeeded
} else if err != nil {
return fmt.Errorf("failed updating employees | %s", err.Error())
}
return nil
}
代码returns出现以下错误:写入异常:写入错误:[无法将数组更新应用于非数组元素组:空]。
我不知道这是什么意思。
也许引擎不喜欢我使用两个 ArrayFilter
的事实?
好的,所以我创建了这个有效的游乐场:https://mongoplayground.net/p/Tznz7btfLkH
实际上问题不是因为请求本身在语法上是有效的。这是因为我在 employee
集合中有另一个文档,看起来像这样:
{
"_id":{
"$oid":"62836aa93c1e2c19eaaac07c"
},
"firstname":"jean",
"lastname":"charles",
"email":"manager@test.co",
"password":"6776c354fce809e7be234f84d0ea907cfd3aba350871a18858ceccc10eabc036",
"salt":"IHaPJIKVVplC8ni",
"organizations":[
{
"organizationid":{
"$oid":"62836aa93c1e2c19eaaac07d"
},
"organizationname":"test",
"ismanager":true,
"groups":null,
"permissions":null
}
]
}
如您所见,此处的 groups
值为空。这就是问题所在。
基本上,当名为 grp
的数组过滤器遇到一个空对象时,它会引发一个错误,因为它不能应用于它。
因此,使请求有效的解决方案是确保集合中的每个文档都初始化了这个 group
数组(即使它是空的,也没关系)。一旦我这样做就没有问题了。