简体   繁体   English

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

[英]Update mongodb document that has multiple arrays of embedded documents using mongoose

Say i have a document that looks like this: 假设我有一个如下所示的文档:

 { "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" } ] } 

My schema is defined in the code snippet below for reference: 我的架构在下面的代码片段中定义以供参考:

 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 }) ] }); 

How would update each array of embedded documents without overwriting the others? 如何在不覆盖其他文档的情况下更新每个嵌入式文档数组?

Say a request is with and address and email object but not phone, how would I handle that? 假设请求是和地址和电子邮件对象但不是电话,我该如何处理?

With mongoose, you can use $push to push object to array. 使用mongoose,您可以使用$ push将对象推送到数组。 The query will be like: 查询将如下:

(saving an address and an email, querying on pid) (保存地址和电子邮件,查询pid)

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

{"pid":1} is the pid of the object you want to update; {“pid”:1}是您要更新的对象的pid;

{$push: {email: emailToPush, address:addressToPush}} is the object you want to push on each array {$ push:{email:emailToPush,address:addressToPush}}是您要在每个阵列上推送的对象

Then you have to filter the body of the request with a middleware or something like that. 然后,您必须使用中间件或类似的东西过滤请求的主体。 I usually use a middleware to check if the request is correct, like: 我通常使用中间件来检查请求是否正确,例如:

EDIT: 编辑:

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

This will build your query object (the second parameter of the update function). 这将构建您的查询对象(更新函数的第二个参数)。

You can try this .. 你可以尝试这个..

Get the structure of the contact object then the check to see what properties were sent in the req.body and build out the query accordingly. 获取联系对象的结构然后检查以查看在req.body中发送了哪些属性并相应地构建查询。

NB: You must have some validation to check the request body to ensure no unwanted properties are sent. 注意:您必须进行一些验证才能检查请求正文,以确保不会发送不需要的属性。 You can use a package like Joi 你可以使用像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} ); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM