MongoDB,从数组中的对象中删除嵌套项
Posted
技术标签:
【中文标题】MongoDB,从数组中的对象中删除嵌套项【英文标题】:MongoDB, remove nested items from objects in arrays 【发布时间】:2020-12-20 13:35:06 【问题描述】:这是我的数据结构:
db.getCollection('competitionmatches').find()
"_id" : ObjectId("5d2d9eed5972a9367cd5010a"),
"matches" : [
"id" : 200000,
"utcDate" : "",
"minute" : null,
"homeTeam" :
"id" : 808,
"coach" : ,
,
"goals" : [,],
,
...,
...,
],
"otherField": []
,
...,
...,
我要删除的是这些字段:minute
、coach
和 goals
,在 matches
中的所有 competitionmatches
中的所有条目中。
我在 Robo 3T 中成功尝试了以下内容:
db.getCollection('competitionmatches').update(, $unset: "otherField":"")
如果我通过multi:true
,这将很好地删除matches
的每个元素中的整个数组otherField
(为了便于阅读,在此处删除)。
但是当我尝试时:
db.getCollection('competitionmatches').update(, $unset: "matches.$[].goals":"")
或
db.getCollection('competitionmatches').update(, $unset: "matches.$[].minute":"")
我收到一条成功消息 Updated 1 existing record(s) in 3ms
但记录保持不变,minute
或 goals
不会被删除。
我从 Remove a field from all elements in array in mongodb 得到了这个答案,并将我的 mongo 版本从 3.4 更新到 3.6,因为 $[]
是在 3.6 中引入的,正如 svr 所说,并在 docs 中显示。
未设置有效,但路径似乎是我更新的错误部分。
"matches.$.goals"
返回错误,matches.[].goals
也没有任何影响。
我什至想知道是否可能有一些缓存,但这没有多大意义,因为otherField
上的未设置执行得很好。
我也怀疑更新是否顺利,但据我所知,使用数据库的应用程序运行良好。
【问题讨论】:
【参考方案1】:更新无法使用$
或$[]
直接访问数组字段,我们需要提供查询以匹配数组,
db.getCollection('competitionmatches').update(
// it requires to specify any one field match condition in query part
"matches.goals": $exists: true ,
$unset:
"matches.$[].minute": true // pass true
"matches.$[].homeTeam.coach": true // pass true
"matches.$[].goals": true // pass true
);
蒙古壳
> db.upd22.find()
[
_id: ObjectId("5d2d9eed5972a9367cd5010a"),
matches: [
id: 200000,
utcDate: '',
minute: null,
homeTeam: id: 808, coach: ,
goals: [ , ]
,
id: 300000,
utcDate: '',
minute: null,
homeTeam: id: 808, coach: ,
goals: [ , ]
]
,
_id: ObjectId("5d2d9eed5972a9367cd5010b"),
matches: [
id: 400000,
utcDate: '',
minute: null,
homeTeam: id: 808, coach: ,
goals: [ , ]
,
id: 500000,
utcDate: '',
> homeTeam: id: 808, coach: ,
goals: [ , ]
]
]
> db.getCollection('upd22').update(
... "matches.goals": $exists: true ,
...
..... $unset:
....... "matches.$[].minute": true,
....... "matches.$[].goals": true
.......
..... ,
... multi: false
... )
acknowledged: 1,
insertedId: null,
matchedCount: 1,
modifiedCount: 1,
upsertedCount: 0
> db.upd22.find()
[
_id: ObjectId("5d2d9eed5972a9367cd5010a"),
matches: [
id: 200000, utcDate: '', homeTeam: id: 808, coach: ,
id: 300000, utcDate: '', homeTeam: id: 808, coach:
]
,
_id: ObjectId("5d2d9eed5972a9367cd5010b"),
matches: [
id: 400000,
utcDate: '',
minute: null,
homeTeam: id: 808, coach: ,
goals: [ , ]
,
id: 500000,
utcDate: '',
minute: null,
homeTeam: id: 808, coach: ,
goals: [ , ]
]
]
>
【讨论】:
刚试过但没有运气。我使用了以下内容:db.getCollection('competitionmatches').update( "matches.goals": $exists: true , $unset: "matches.$[].minute": true, "matches.$[].goals": true , multi:false )
注意,coach
在 homeTeam
对象内。
它从第一个文档中删除两个字段,这对您不起作用?
我得到一个“更新的 1 条现有记录”作为结果,但是当用新的 find()
刷新数据时,我仍然可以在数组的至少前两个条目中看到两个字段matches
.
我已将查询范围缩小到特定的competitionMatches
,ID 为db.getCollection('competitionmatches').update( "_id": ObjectId("5d2d9eed5972a9367cd5010a"), "matches.goals": $exists: true , $unset: "matches.$[].minute": true, "matches.$[].goals": true , multi:false )
刚刚做了一个快速测试,通过在competitionMatches
的根部添加字段temporary
上方的id 并使用db.getCollection('competitionmatches').update( "_id": ObjectId("5d2d9eed5972a9367cd5010a"), "matches.goals": $exists: true , $unset: "tempo":true, "matches.$[].minute": true, "matches.$[].goals": true , multi:false )
将其删除,它工作正常。所以我猜问题是真正进入数组并找到所需的字段。以上是关于MongoDB,从数组中的对象中删除嵌套项的主要内容,如果未能解决你的问题,请参考以下文章