【问题标题】:MongoDB, remove nested items from objects in arraysMongoDB,从数组中的对象中删除嵌套项
【发布时间】: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 上的未设置执行得很好。

我也怀疑更新是否顺利,但据我所知,使用数据库的应用程序运行良好。

【问题讨论】:

    标签: mongodb unset


    【解决方案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 }) 将其删除,它工作正常。所以我猜问题是真正进入数组并找到所需的字段。
    猜你喜欢
    • 1970-01-01
    • 2021-07-03
    • 2021-04-19
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多