【问题标题】:$set operator mongo deletes non existing keys?$set operator mongodb 删除不存在的键?
【发布时间】:2017-10-13 15:06:45
【问题描述】:

当我运行这个命令时:

var news = {
    _id: req.body.newsItemId,
    images: {
        _id: new ObjectId(),
        src: result
    }
}

Shop.findOneAndUpdate({
    _id: ObjectId(req.body.shopId), 
    'news._id':  ObjectId(req.body.newsItemId)},
    {"$set": {
        "news.$": news
    }
}).exec(function(err, shop){
    console.log(err, shop);

})

news 对象中不存在的字段被空值覆盖,因此它们被从文档中删除。

news 是来自商店的子文档。所以一个文档看起来像:

name: 'test shop',
email: 'email@shop',
products: [],
news: [
    {
       name: 'test news',
       content: 'lorum ipsum....',
       summary: 'lorum',
       images: [
          {
             src: 'news/image_1.jpg',
          }
       ]
    }
]

运行上面的命令后,消息只包含一个id和1个图像。我只想覆盖 images 数组,不理会其他属性。我已经尝试过仅使用集合中的图像,但随后出现此错误 Mongoose update 'cannot use the part (..) to traverse the element ,这就是 $ 的来源。

【问题讨论】:

  • 好吧'news.$': news 基本上会覆盖整个匹配的对象,因为这就是你告诉它要做的事情。你总是可以做类似$set: { 'news.$.content': newContent } 的事情,它只更新那个元素。嵌套数组确实不是一个明智的主意,在 MongoDB 3.6 之前甚至不支持更新,而且查询起来仍然很痛苦。因此,不清楚您是打算“更新”内部“图像”数组中的条目还是“追加”一个新条目到内部数组。后者很简单。没有硬编码的索引,前者目前是不可能的。
  • 谢谢。其实很简单。将 $set 更改为:news.$.images 并将变量更改为 [{src: 'image.jpg'}]

标签: mongodb


【解决方案1】:

通过将代码更改为这个来解决这个问题:

var images = [{
    src: result
}]


Shop.findOneAndUpdate({
    _id: ObjectId(req.body.shopId), 
    'news._id':  ObjectId(req.body.newsItemId)},
    {"$set": {
        "news.$.images" : images 
    }
    }).exec(function(err, shop){
        console.log(err, shop);
        return res.status(200).json({message: 'OK'});
    })

所以现在只有图像对象被覆盖,这就是我想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 1970-01-01
    • 2016-08-13
    • 2019-03-31
    • 1970-01-01
    • 2016-05-27
    • 2014-07-03
    相关资源
    最近更新 更多