MongoDB更新子文档更改其_id

时间:2018-01-28 20:05:58

标签: node.js mongodb mongoose

我有下一个文档,我想更新ID为21的地址,将别名更改为&#39; Family&#39;。我运行 <include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent" />

哪种工作正常,带来恼人的副作用,是Mongo为子文档生成一个新的id。有没有办法更新子文档而不获取新的ID?

User.update({ _id: 2, 'addresses._id': 21 }, { 'addresses.$': newAddress });

我已经使用

解决了这个问题
'user': {
  '_id': 2,
  'addresses': [
    {
      '_id': '20',
      'alias': 'Work',
      'postal_code': 1235
    },
    {
      '_id': '21',
      'alias': 'Home',
      'postal_code': 1235
    }
  ]
}

这并没有改变子文档的ID,但出于显而易见的原因,我不喜欢这个解决方案。

2 个答案:

答案 0 :(得分:2)

简短的回答是:不。本质上,更新对象{ 'addresses.$': newAddress }是用newAddress对象替换匹配指针位置处的整个对象的命令。也就是说,如果newAddress对象包含_id值,则应将其存储为值。

答案 1 :(得分:0)

添加到JasonCust的答案中,正确的方法是将旧ID注入新地址,以保持ID不变并避免必须输入每个单独的密钥。

下面是一个示例:

  const userSchema = new Schema({
    addresses: [{ country: String }]
  });

  const User = mongoose.model('User', userSchema);
  const user = await User.create({
    addresses: [
      { country: 'Egypt' }
    ]
  });

  const oldAddressId = user.addresses[0]._id;

  //
  const newAddress = {
    _id: oldAddressId,
    country: 'Japan'
  };

  await User.updateOne({ 'addresses._id': oldAddressId }, { 'addresses.$': newAddress });
  const userAfterUpdate = await User.findOne({ _id: user._id });

  assert.equal(userAfterUpdate.addresses[0].country, 'Japan');
  assert.equal(userAfterUpdate.addresses[0]._id.toString(), oldAddressId.toString());