2015-05-15 4 views
15

Ich habe eine Übersichtstabelle, die wie so aussieht:RethinkDB - verschachtelte Array aktualisiert

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

ich die score und feedback Felder unter einem bestimmten Kontakt aktualisiert müssen. Derzeit bin ich das Update wie folgt ausgeführt werden:

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

Als ich im update Methode suchen, gibt es, wie verschachtelte Schlüssel zu aktualisieren: Wert-Paaren. Ich kann jedoch keine Beispiele finden, um ein einzelnes Element in einem Array zu aktualisieren.

Gibt es eine bessere und hoffentlich sauberere Möglichkeit, Elemente in einem verschachtelten Array zu aktualisieren?

Antwort

10

Möglicherweise müssen Sie das Array filter den gewünschten Wert im Array herausnehmen und es dann erneut an das Array anfügen. Dann können Sie das aktualisierte Array an die Methode update übergeben.

Beispiel

Lassen Sie uns sagen, dass Sie ein Dokument mit zwei Clients haben, die beide eine name und eine score und Sie die Partitur in einem von ihnen zu aktualisieren:

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

Sie bekommen Führen Sie in diesem spezifischen Dokument den Befehl update mit einer anonymen Funktion aus, und übergeben Sie das neue aktualisierte Array an die Eigenschaft 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 }) 
    }; 
    }); 

Ich denke, das ist ein wenig umständlich ist, und es ist wahrscheinlich eine schöne, elegante Art und Weise, dies zu tun, aber das sollte Ihr Problem lösen.

Datenbank-Schema

Vielleicht ist es lohnt sich eine contacts Tisch für alle Ihre Kontakte zu schaffen und tun dann ein eine Art auf Sie Daten zu verbinden. Dann wird Ihr contacts Eigenschaft in Ihrem clients Array würde in etwa so aussehen:

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

es funktioniert für mich

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

Datenbankschema

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

dann können Sie tun, wie diese map mit und branch Abfrage.

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