【问题标题】:Deleting array object in Meteor/MongoDB在 Meteor/MongoDB 中删除数组对象
【发布时间】:2025-12-08 18:15:02
【问题描述】:

我正在尝试删除数组中的一个对象,我在 Meteor.update 中尝试了拉取和取消设置,但是整个数组被删除了,而不仅仅是数组中的单个对象。

我尝试过的代码

Cars.update( 
    { _id: id},
    { $unset: { 'models': { '$.id': modelId  }  } })

Cars.update( 
{ _id: id},
{ $pull: { 'models': { 'id': modelId  }  } })

在这两种情况下,整个 'models' 属性都被删除了,而不仅仅是数组中的一个对象

汽车架构:

models : {
type: [Object],
optional: true
},

'models.$.id': {
type: String,
autoValue: function() {
    return Meteor.uuid()
},
optional: true
}

本质上,集合“汽车”包含一个数组“模型”,它是一个对象数组(汽车模型)。每个汽车模型对象都有一个属性 id。我想使用属性“id”从模型数组中删除单个汽车模型,但我上面的尝试删除了整个“模型”数组而不是单个对象。任何帮助,将不胜感激。谢谢

之前

{
"_id" : "XxbKzS6GHthxwnLFq",
"createdAt" : ISODate("2018-05-04T08:05:59.151Z"),
"updatedAt" : ISODate("2018-05-04T08:36:11.785Z"),
"models" : [ 
    {
        "name" : "Mercedes",
        "id" : "9927cfe1-f5ae-4625-b6eb-87868793a229"
    }, 
    {
        "name" : "BMW",
        "id" : "86f24e9d-dd08-4407-b350-63d9b25dc094"
    }
]
}

之后

{
"_id" : "XxbKzS6GHthxwnLFq",
"createdAt" : ISODate("2018-05-04T08:05:59.151Z"),
"updatedAt" : ISODate("2018-05-04T09:38:56.470Z")
}

父对象是 XxbKz...,它包含一个属性模型,它是一个对象数组(BMW,Mercedes)。我想从 XxbKz 父对象中删除 BMW 对象。我使用其 id (XxbKz...) 查询父对象,并使用其 id (86f2...) 查询 BMW 对象(原始帖子中的代码)。结果是整个模型数组都被删除了(BMW 和 Mercedes),而不仅仅是 BMW。

我的流星电话是

Meteor.call('deleteCar','XxbKzS6GHthxwnLFq','86f24e9d-dd08-4407-b350- 
    63d9b25dc094') 

deleteCar(carId, modelId) {
check(carId, String)
check(modeld, String)
if (Meteor.isServer) {
    let car = Cars.update( {_id: carId},
      { $pull: { 'models': { 'id': modelId  }  } }
    )   
    console.log(car)
    return car
  }
}

}

deleteCar 函数中的变量是 carId(XxbK) 和 modelId(86f2),它们是 deleteCar 流星调用的第一个和第二个参数。据我了解,应该只删除父母的宝马,但由于某种原因,情况并非如此

【问题讨论】:

  • 唯一正确的当然是$pull,因为$unset 完全是做别的事情。是否愿意展示一份实际文档以及您发送的您希望匹配的值?请注意,$pull 将删除与提供的条件匹配的“所有内容”。因此,如果您有多个匹配相同条件的数组元素,则需要删除它们中的“全部”。显示一个文档,这样我们就可以在这里看到您可能做错了什么。
  • @NeilLunn 对所有删除的 cmets 感到抱歉。我打算按回车键转到下一行,但它提交了我的评论。我现在已经在原帖中添加了图片
  • 我认为关键是要解决您打开“文本”视图选项卡并复制“文本”而不​​是图像的问题。我现在不能将“图像”复制到我自己的集合中并自己运行语句,可以吗?但是,我可以用“文本”来做到这一点。当您无法发布图片时,这就是您应该学习的课程。
  • @NeilLunn 啊,这很有道理!我再次编辑了原始帖子以符合指南

标签: mongodb meteor


【解决方案1】:

这可以从您的示例中删除梅赛德斯。

db.cars.update({_id: 'XxbKzS6GHthxwnLFq'}, {$pull: {models: {id: '9927cfe1-f5ae-4625-b6eb-87868793a229'}}})

看起来很像

 Cars.update( 
{ _id: id},
{ $pull: { 'models': { 'id': modelId  }  } })

我确实从 mongo shell 而不是流星运行了这个。不过我在 Meteor 中使用 $pull 没问题。

我从未使用过返回更新,它很可能是在更新之前返回原始文档。我会添加这个。

Cars.update( {_id: carId},
      { $pull: { 'models': { 'id': modelId  }  } }
    )       
const car = Cars.findOne(carId)
console.log(car)
return car

祝你好运,让我知道你过得怎么样。

【讨论】:

  • 感谢您的回复!您的方法适用于 mongo shell,但不适用于流星。但是,我确实设法找出了问题,在我使用的架构框架(SimpleSchema)的验证过程中存在一个错误,解决方案是在 update() 中传递 getAutoValues:false ,这使得拉取工作没有问题