RethinkDB – 更新嵌套数组

我有一个调查表,看起来像这样:

{ id: Id, date: Date, clients: [{ client_id: Id, contacts: [{ contact_id: Id, score: Number, feedback: String, email: String }] }] } 

我需要更新特定联系人下的scorefeedback字段。 目前,我正在运行这样的更新:

 function saveScore(obj){ var dfd = q.defer(); var survey = surveys.get(obj.survey_id); survey .pluck({ clients: 'contacts' }) .run() .then(results => { results.clients.forEach((item, outerIndex) => { item.contacts.forEach((item, index, array) => { if(Number(item.contact_id) === Number(obj.contact_id)) { array[index].score = obj.score; console.log(outerIndex, index); } }); }); return survey.update(results).run() }) .then(results => dfd.resolve(results)) .catch(err => dfd.resolve(err)); return dfd.promise; }; 

当我查看更新方法时,它指定如何更新嵌套的键值对。 但是,我找不到任何示例来更新数组中的单个项目。

有没有更好的,希望更清洁的方式来更新嵌套数组中的项目?

您可能需要获取数组,在数组中filter出所需的值,然后再将其附加到数组中。 然后您可以将更新的数组传递给update方法。

比方说,你有一个文件与两个客户端,都有一个name和一个score ,你想要更新其中之一的分数:

 { "clients": [ { "name": "jacob" , "score": 200 } , { "name": "jorge" , "score": 57 } ] , "id": "70589f08-284c-495a-b089-005812ec589f" } 

您可以获取该特定文档,使用匿名函数运行update命令,然后将新的更新数组传递到clients属性中。

 r.table('jacob').get("70589f08-284c-495a-b089-005812ec589f") .update(function (row) { return { // Get all the clients, expect the one we want to update clients: row('clients').filter(function (client) { return client('name').ne('jorge') }) // Append a new client, with the update information .append({ name: 'jorge', score: 57 }) }; }); 

我认为这有点麻烦,可能有更好,更优雅的做法,但这应该可以解决您的问题。

数据库模式

也许值得为所有的联系人创build一个contacts表,然后对你的数据做一些联接。 那么你的clients数组中的contacts属性将如下所示:

 { id: Id, date: Date, clients: [{ client_id: Id, contact_scores: { Id: score(Number) }, contact_feedbacks: { Id: feedback(String) } }] } 

这个对我有用

 r.table(...).get(...).update({ contacts: r.row('Contacts').changeAt(0, r.row('Contacts').nth(0).merge({feedback: "NICE"})) })