更新MongoDB中的子文档数组

本吉曼

我有一组学生,这些学生有一个姓名和一组电子邮件地址。学生文档看起来像这样:

{
  "_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
  "name": "John Doe",
  "emails": [
    {
      "label": "private",
      "value": "[email protected]"
    },
    {
      "label": "work",
      "value": "[email protected]"
    }
  ]
}

电子邮件子文档中的标签被设置为每个文档唯一,因此不能有两个标签相同的条目。

我的问题是,在更新学生文档时,我想要实现以下目标:

  • 添加带有新标签的电子邮件应该只需将具有给定标签和值的新子文档添加到数组中
  • 如果添加带有已存在标签的电子邮件,则应将现有值设置为更新数据

例如,当更新以下数据时:

{
  "_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
  "emails": [
    {
      "label": "private",
      "value": "[email protected]"
    },
    {
      "label": "school",
      "value": "[email protected]"
    }
  ]
}

我希望emails数组的结果是:

"emails": [
    {
      "label": "private",
      "value": "[email protected]"
    },
    {
      "label": "work",
      "value": "[email protected]"
    },
    {
      "label": "school",
      "value": "[email protected]"
    }
  ]

我如何在MongoDB中实现这一目标(可以选择使用mongoose)?这是完全可能的,还是我必须在应用程序代码中亲自检查数组?

本吉曼

在研究了发布的不同选项之后,我决定使用自己的方法,使用lodash的unionBy()函数在代码中手动进行更新使用express和mongoosefindById()基本上看起来像这样:

Student.findById(req.params.id, function(err, student) {

    if(req.body.name) student.name = req.body.name;
    if(req.body.emails && req.body.emails.length > 0) {
        student.emails = _.unionBy(req.body.emails, student.emails, 'label');
    }

    student.save(function(err, result) {
        if(err) return next(err);
        res.status(200).json(result);
    });

});

这样,我可以获得所有字段的部分更新的全部灵活性。当然,您也可以使用findByIdAndUpdate()或其他选项。

替代方法:

但是,像Vince Bowdren建议的那样更改模式的方法,label在电子邮件子文档中创建单个单独的字段,也是可行的选择。最后,这仅取决于您的个人喜好以及是否需要对数据进行严格验证。

如果像我一样使用猫鼬,则必须定义一个单独的架构,如下所示:

var EmailSchema = new mongoose.Schema({
  work: { type: String, validate: validateEmail },
  private: { type: String, validate: validateEmail }
}, {
  strict: false,
  _id: false
});

在模式中,您可以为已经要支持的标签定义属性并添加验证。通过设置该strict: false选项,您将允许用户还发布带有自定义标签的电子邮件。但是请注意,这些将不会被验证。您将必须在我的应用程序中手动应用验证,类似于我在上面的合并方法中所做的验证。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章