用Mongoose和Node更新多个子文档

我有一个包含一系列子文档的模型。 这是一个Company

 { "_id" : ObjectId(":58be7c236dcb5f2feff91ac0"), "name" : "sky srl", "contacts" : [ { "_id" : ObjectId("58be7c236dcb5f2feff91ac2"), "name": { type: String, required: true }, "company" : ObjectId("58be7c236dcb5f2feff91ac0"), "email" : "sky@gmail.com", "chatId" : "", "phone" : "123456789", "name" : "John Smith" }, { "_id" : ObjectId("58be7f3a6dcb5f2feff91ad3"), "company" : ObjectId("58be7f3a6dcb5f2feff91ad1"), "email" : "beta@gmail.com", "chatId" : "", "phone" : "987654321", "name" : "Bill Gaset" } ], "__v" : 1 } 

我有几家公司,我想更新所有公司所有联系人的字段聊天ID,这与我正在寻找的phone相匹配。

我的模式定义(简化,专注于问题):

 var contactSchema = new Schema({ [...] phone: { type: String, required: true }, email: { type: String }, chatId: { type: String }, company: Schema.Types.ObjectId, }); var companySchema = new Schema({ name: { type: String, required: true }, type: { type: String, default: "company" }, contacts: [contactSchema] }); 

我试过了

 var conditions = { "contacts.phone": req.body.phone }; var partialUpdate = req.body; //it contains 'req.body.phone' and 'req.body.chatId' attributes Company.find(conditions).then( function (results) { results.map( function(companyFound) { companyFound.contacts.forEach(function (contactContainer){ if (contactContainer.phone == partialUpdate.phone) { contactContainer.chatId = partialUpdate.chatId; Company.save(); companyFound.save(); contactContainer.save(); results.save(); } //not sure of what to save, so i save everything companyFound.save(); contactContainer.save(); results.save(); }); }); }); 

在这个答案之后 ; 但它不起作用。 它不保存任何东西,我做错了什么?

我从来没有这样做过,但值得一试。

也许你需要使用$ elemMatch 。

 // find the companies that have contacts having the phone number Company.find().where('contacts', { $elemMatch: { phone: req.body.phone }}).exec(function (err, companies) { if (err) { console.log(err); return; } // see if you can at least get the query to work console.log(companies); async.eachSeries(companies, function updateCompany(company, done) { // find and update the contacts having the phone number company.contacts.forEach(function (contact, i, arr) { if (contact.phone == req.body.phone) { arr[i].chatId = req.body.chatId; } }); company.save(done); }, function allDone (err) { console.log(err); }); }); 

请注意,我正在使用async.js在多个项目上执行asynchronous操作。

说实话,我只是简单地使contacts数组Contact 引用 – 更容易查询和更新。

只是为了logging:我这样做,使其工作没有async.js:

 Company.find().where('contacts', { $elemMatch: { phone: req.body.phone } }) .exec(function (err, companies) { if (err) { console.log(err); return; } console.log("companies: " + JSON.stringify(companies, null, 4)); companies.forEach(function (company) { company.contacts.map(function (contact, i, arr) { if (contact.phone == req.body.phone) { arr[i].telegramChatId = req.body.telegramChatId; } }); company.save(); }, function allDone(err) { console.log(err); }); });`