arrays - 更新 MongoDB 中的子文档数组

标签 arrays mongodb mongoose updates

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

{
  "_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
  "name": "John Doe",
  "emails": [
    {
      "label": "private",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1a6a68736c7b6e7f5a707572747e757f34797577" rel="noreferrer noopener nofollow">[email protected]</a>"
    },
    {
      "label": "work",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5b2c3429301b313433353f343e75383436" rel="noreferrer noopener nofollow">[email protected]</a>"
    }
  ]
}

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

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

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

例如,使用以下数据更新时:

{
  "_id": {"$oid": "56d06bb6d9f75035956fa7ba"},
  "emails": [
    {
      "label": "private",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9af7ffdaf0f5f2f4fef5ffb4f9f5f7" rel="noreferrer noopener nofollow">[email protected]</a>"
    },
    {
      "label": "school",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e291818a8d8d8ea2888d8a8c868d87cc818d8f" rel="noreferrer noopener nofollow">[email protected]</a>"
    }
  ]
}

我希望电子邮件数组的结果是:

"emails": [
    {
      "label": "private",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e9848ca9838681878d868cc78a8684" rel="noreferrer noopener nofollow">[email protected]</a>"
    },
    {
      "label": "work",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f58405d446f454047414b404a014c4042" rel="noreferrer noopener nofollow">[email protected]</a>"
    },
    {
      "label": "school",
      "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7a4b4bfb8b8bb97bdb8bfb9b3b8b2f9b4b8ba" rel="noreferrer noopener nofollow">[email protected]</a>"
    }
  ]

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

最佳答案

您可以尝试此更新,但仅对小型数据集有效:

mongo shell:

var data = {
    "_id": ObjectId("56d06bb6d9f75035956fa7ba"),
    "emails": [
        {
          "label": "private",
          "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9ef3fbdef4f1f6f0faf1fbb0fdf1f3" rel="noreferrer noopener nofollow">[email protected]</a>"
        },
        {
          "label": "school",
          "value": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b9cadad1d6d6d5f9d3d6d1d7ddd6dc97dad6d4" rel="noreferrer noopener nofollow">[email protected]</a>"
        }
    ]
};

data.emails.forEach(function(email) {
    var emails = db.students.findOne({_id: data._id}).emails,
        query = { "_id": data._id },
        update = {};

    emails.forEach(function(e) {
        if (e.label === email.label) {
            query["emails.label"] = email.label;
            update["$set"] = { "emails.$.value": email.value };
        } else {
           update["$addToSet"] = { "emails": email }; 
        }
        db.students.update(query, update)
    });
});

关于arrays - 更新 MongoDB 中的子文档数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39125838/

相关文章:

javascript - 如何从对象中获取对象数组(不是值,不是字符串,不仅是键)?

asp.net - 自定义排序文件名字符串数组

java - 如何在 Java 中创建对象数组的 ArrayList?

java - 用一个错误命名的字段使 MongoDB 崩溃,它有什么特别之处?

Node.js:Mongoose initializeUnorderedBulk 返回 null

node.js - 资源状态 500。消息 : Internal server error find product by name and price

arrays - MongoDB 替换特定的数组值

MongoDB 计数查询优化

javascript - 如何向 JSON 对象添加特殊的 Mongo 表达式?

node.js - Mongoose - 仅返回数组的内容,而不返回其名称