2015-05-15 15 views
15

Mam tabeli ankietę, która wygląda tak:RethinkDB - Aktualizacja zagnieżdżonego tablicę

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

Ptrzebuję aktualizowanych pól score i feedback ramach określonego kontaktu. Obecnie używam aktualizację tak:

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

Kiedy patrzę na metodzie update, określa jak zaktualizować klucz zagnieżdżone: par wartości. Jednak nie mogę znaleźć żadnych przykładów aktualizacji pojedynczego elementu w tablicy.

Czy istnieje lepszy i miejmy nadzieję czystszy sposób aktualizowania elementów w zagnieżdżonej tablicy?

Odpowiedz

10

Być może trzeba będzie uzyskać tablicę, filter z żądanej wartości w tablicy, a następnie dołączyć ją ponownie do tablicy. Następnie możesz przekazać zaktualizowaną tablicę do metody update.

Przykład

Powiedzmy masz dokument z dwoma klientami, że oba mają name i score i chcesz zaktualizować wynik w jednym z nich:

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

można dostać tego konkretnego dokumentu, uruchom komendę update z funkcją annonymous, a następnie przekaż nową, zaktualizowaną tablicę do właściwości 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 }) 
    }; 
    }); 

Sądzę, że jest to trochę uciążliwe i prawdopodobnie jest to lepszy, bardziej elegancki sposób na zrobienie tego, ale powinno to rozwiązać twój problem.

Schemat bazy danych

Może warto stworzyć contacts tabelę dla wszystkich swoich kontaktów, a następnie zrobić jakiś dołączyć na ciebie danych. Następnie nieruchomość w macierzy clientscontacts będzie wyglądać mniej więcej tak:

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

to działa na mnie

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

schematu bazy danych

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

wtedy można zrobić tak użyciu map i zapytanie branch.

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)}) 
    }) 
Powiązane problemy