RethinkDB - 更新嵌套数组

Jac*_*ner 16 javascript database node.js rethinkdb

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

{
  id: Id,
  date: Date,
  clients: [{
    client_id: Id,
    contacts: [{
      contact_id: Id,
      score: Number,
      feedback: String,
      email: String
    }]
  }]
}
Run Code Online (Sandbox Code Playgroud)

我需要更新特定联系人下的字段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;
};
Run Code Online (Sandbox Code Playgroud)

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

是否有更好的,更有希望更新的方式来更新嵌套数组中的项目?

Jor*_*lva 9

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

假设您有一个包含两个客户端的文档,这两个客户端都有a name和a,score并且您希望更新其中一个得分:

{
  "clients": [
    {
      "name":  "jacob" ,
      "score": 200
    } ,
    {
      "name":  "jorge" ,
      "score": 57
    }
  ] ,
  "id":  "70589f08-284c-495a-b089-005812ec589f"
}
Run Code Online (Sandbox Code Playgroud)

您可以获取该特定文档,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 })
    };
  });
Run Code Online (Sandbox Code Playgroud)

我认为这有点麻烦,并且可能有更好,更优雅的方式,但这应该可以解决您的问题.

数据库架构

也许值得contacts为所有联系人创建一个表,然后对您的数据进行某种联接.然后你contactsclients数组中的属性看起来像:

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


zab*_*usa 6

数据库架构

{
  "clients": [
    {
      "name":  "jacob" ,
      "score": 200
    } ,
    {
      "name":  "jorge" ,
      "score": 57
    }
  ] ,
  "id":  "70589f08-284c-495a-b089-005812ec589f"
}
Run Code Online (Sandbox Code Playgroud)

那么你可以像这样使用mapbranch查询。

r.db('users').table('participants').get('70589f08-284c-495a-b089-005812ec589f')
  .update({"clients": r.row('clients').map(function(elem){
     return r.branch(
      elem('name').eq("jacob"),
      elem.merge({ "score": 100 }),
      elem)})
    })
Run Code Online (Sandbox Code Playgroud)