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": []
,
...,
...,

我要删除的是这些字段:minutecoachgoals,在 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 但记录保持不变,minutegoals 不会被删除。

我从 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 ) 注意,coachhomeTeam 对象内。 它从第一个文档中删除两个字段,这对您不起作用? 我得到一个“更新的 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,从数组中的对象中删除嵌套项的主要内容,如果未能解决你的问题,请参考以下文章

删除嵌套组中的重复项

从嵌套数组mongodb中删除元素

从嵌套数组mongodb中删除元素

如何从 MongoDB 文档中的双重嵌套数组中删除元素。

获取嵌套数组/对象的数组中的所有唯一值(删除重复项)

从 mongodb 数组中的所有重复项中拉出一个元素