猫鼬findByIdAndUpdate销毁丢失的字段

时间:2019-12-26 06:42:51

标签: node.js mongodb mongoose mongodb-query

开发一个node.js api。我有显示场地的mongo数据。例如,它包含一个地址。...

    "address": {
        "street": "123 main st",
        "city": "seomwhere",
        "state": "FL",
        "zip": "33222"
    },
       :

当我发布到更新端点并像这样发送正文时,它会更新地址,但是会删除那里的所有其他字段。...

"address": { 
    "zip": "33222"
}

因此,在数据库中,街道,城市,州都丢失了。这是我的一段代码...

venue = await Venue.findByIdAndUpdate(req.params.id, req.body, {
  new: true,
  runValidators: true
});

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

因为地址在主体("address": { "zip": "33222" })中仅包含单个键,所以它将地址对象内的其他值替换为数据库中的空白值。

因此,要解决该问题,必须对.对象使用address表示法。喜欢

venue = await Venue.findByIdAndUpdate(
  req.params.id,
  { $set: { "address.zip": "33222" },
  { new: true, runValidators: true }
)

但是由于您无法确定address对象中的哪些键以及根级别将被更新

const object = req.body

for (var key in req.body.address) {
  object[`address.${key}`] = object.address[key]
}
delete object.address

venue = await Venue.findByIdAndUpdate(
  req.params.id,
  { $set: object },
  { new: true, runValidators: true }
)

答案 1 :(得分:1)

在请求正文中未指定时,您正在覆盖现有地址字段。

您只需要更新请求正文中的字段:

  const fields = {};

  Object.keys(req.body.address).forEach(key => {
    fields[`address.${key}`] = req.body.address[key];
  });

  const venue = await Venue.findByIdAndUpdate(req.params.id, fields, {
    new: true,
    runValidators: true
  });

比方说我们有这个场地文件:

{
    "_id": "5e047d4e10be4f0da4c61703",
    "name": "Venue 1",
    "address": {
        "street": "123 main st",
        "city": "seomwhere",
        "state": "FL",
        "zip": "33222"
    },
    "__v": 0
}

当您使用像这样的requset主体时:

{
    "address": {
        "zip": "33333"
    }
}

响应将是:

{
    "address": {
        "street": "123 main st",
        "city": "seomwhere",
        "state": "FL",
        "zip": "33333"
    },
    "_id": "5e047d4e10be4f0da4c61703",
    "name": "Venue 1",
    "__v": 0
}

当我们想要这样更新时:

{
    "address": {
        "state": "NY",
        "zip": "44444"
    }
}

响应将是:

{
    "address": {
        "street": "123 main st",
        "city": "seomwhere",
        "state": "NY",
        "zip": "44444"
    },
    "_id": "5e047d4e10be4f0da4c61703",
    "name": "Venue 1",
    "__v": 0
}