使用mongoose更新具有多个嵌入式文档数组的mongodb文档

时间:2019-02-26 17:22:12

标签: node.js mongodb express mongoose

说我有一个看起来像这样的文档:

{
  "personId": 13998272,
  "address": [
    {
      "addressType": "HOME",
      "streetNo": 21,
      "addressLine1": "LORRAINE AVENUE",
      "addressLine2": "EDGEWATER",
      "city": "KINGSTON",
      "parish": "ST ANDREW",
      "country": "JAMAICA",
      "qScore": 0.9,
      "modifiedDate": "2019-02-17 15:24:19"
    }
  ],
  "phone": [
    {
      "originalNumber": "+18767842983",
      "phoneNumberIFormat": "+18768514679",
      "phoneNumberLFormat": "8768514679",
      "qualityScore": 0.8,
      "dataSource": "PERSON",
      "modifiedDate": "2018-12-17 09:42:31"
    }
  ],
  "email": [
    {
      "emailAddress": "neilagreen78@yahoo.com",
      "dataSource": "FINACLE",
      "qualityScore": 0.89,
      "modifiedDate": "2018-12-17 09:38:41"
    }
  ]
}

下面的代码段中定义了我的架构,以供参考:

const contactSchema = new mongoose.Schema({
  pid: Number,
  address: [
    new mongoose.Schema({
      addressType: String,
      streetNo: String,
      addressLine1: String,
      addressLine2: String,
      city: String,
      parish: String,
      country: String,
      qScore: String,
      modifiedDate: String
    })
  ],
  phone: [
    new mongoose.Schema({
      originalNumber: String,
      phoneNumberIFormat: String,
      phoneNumberLFormat: String,
      qualityScore: Number,
      dataSource: String,
      modifiedDate: String
    })
  ],
  email: [
    new mongoose.Schema({
      emailAddress: String,
      dataSource: String,
      qualityScore: Number,
      modifiedDate: String
    })
  ]
});

如何在不覆盖其他嵌入文档的情况下更新每个嵌入文档的数组?

说请求与地址和电子邮件对象有关,但没有电话,我该如何处理?

2 个答案:

答案 0 :(得分:3)

使用猫鼬,您可以使用$ push将对象推入数组。查询如下:

(保存地址和电子邮件,在pid上查询)

db.getCollection("contactSchema").update({"pid":1}, {$push: {email: emailToPush, 
address:addressToPush}})

{“ pid”:1}是您要更新的对象的pid;

{$ push:{email:emailToPush,address:addressToPush}}是要在每个阵列上推送的对象

然后,您必须使用中间件或类似的东西过滤请求的主体。我通常使用中间件来检查请求是否正确,例如:

编辑:

const buildQuery = (requestBody) => {
    let query = {$push: {}};
    Object.keys(requestBody).map(key => {
        query.$push[key] = requestBody[key];
    });
}

这将构建您的查询对象(更新功能的第二个参数)。

答案 1 :(得分:3)

您可以尝试这个..

获取联系人对象的结构,然后检查以查看req.body中发送了哪些属性,并相应地构建查询。

N.B:您必须具有一些验证才能检查请求正文,以确保不发送不需要的属性。您可以使用Joi

之类的软件包

   
const getContact = await contact.findOne({ id: req.params.id });

let query = { $addToSet: {} };
  for (let key in req.body) {
    if (getContact[key] && getContact[key] !== req.body[key])// if the field we have in req.body exists, we're gonna update it
      query.$addToSet[key] = req.body[key];
  }

  const contact = await Customer.findOneAndUpdate(
    { pid: req.params.id },
    query,
    {new: true}
  );