2017-04-18 60 views
2

我有一個模型,它包含一個子文檔數組。這是一個Company用Mongoose和Node更新多個子文檔

{ 
"_id" : ObjectId(":58be7c236dcb5f2feff91ac0"), 
"name" : "sky srl", 

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

我有幾個公司,我想更新所有聯繫人的所有公司領域chatId,該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(); 
       }); 
      }); 
}); 

下面這個answer;但它不起作用。它不保存任何東西,我做錯了什麼?

+0

的Pinpoint在第一次失敗。是查詢還是更新?什麼是'partialUpdate'?可能也是一個好主意,以顯示您的架構。 – Mikey

+0

好的,查詢失敗,如果我使用 'Company.find(conditions).then(function(results){})',id不會失敗。 我會加'partialUpdate' var,我忘了它,謝謝! – Diego

+0

我試過了,但是 'var conditions = {「phone」:req.body.phone}; Contact.find(條件)。然後( 函數(結果){ 的console.log( 「結果:」 + JSON.stringify(結果,空值,4)); } );' 示出了一個空陣 – Diego

回答

1

我從來沒有這樣做過,但值得一試。您可能需要使用$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對多個項目執行異步操作。

老實說,我只是簡單地做了contacts一組Contactreferences - 更容易查詢和更新。

+0

非常感謝@Mikey! 我只是修改它有點沒有async.js(這是一個有趣的圖書館),工作! – Diego

1

只是爲了記錄:我這樣做是爲了使其不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); 
       }); 
      });`