RethinkDB - Updating nested array

后端 未结 6 1230
深忆病人
深忆病人 2021-02-13 01:42

I have a survey table that looks like so:

{
  id: Id,
  date: Date,
  clients: [{
    client_id: Id,
    contacts: [{
      contact_id: Id,
      score: Number,
         


        
6条回答
  •  梦毁少年i
    2021-02-13 02:19

    tfmontague is on the right path but I think his answer can be improved a lot. Because he uses ...(0) there's a possibility for his answer to throw errors.

    zabusa also provides a ReQL solution using map and branch but doesn't show the complete nested update. I will expand on this technique.

    ReQL expressions are composable so we can isolate complexity and avoid repetition. This keeps the code flat and clean.

    First write a simple function mapIf

    const mapIf = (rexpr, test, f) =>
      rexpr.map(x => r.branch(test(x), f(x), x));
    

    Now we can write the simplified updateClientContact function

    const updateClientContact = (doc, clientId, contactId, patch) =>
      doc.merge
      ( { clients:
            mapIf
            ( doc('clients')
            , c => c('client_id').eq(clientId)
            , c =>
                mapIf
                ( c('contacts')
                , c => c('contact_id').eq(contactId)
                , c =>
                    c.merge(patch)
                )
            )
        }
      );
    

    Use it like this

    // fetch the document to update
    const someDoc =
      r.db(...).table(...).get(...);
    
    // create patch for client id [1] and contact id [12]
    const patch =
      updateClientContact(someDoc, 1, 12, { name: 'x', feedback: 'z' });
    
    // apply the patch
    someDoc.update(patch);
    

    Here's a concrete example you can run in reql> ...

    const testDoc =
      { clients:
          [ { client_id: 1
            , contacts:
                [ { contact_id: 11, name: 'a' }
                , { contact_id: 12, name: 'b' }
                , { contact_id: 13, name: 'c' }
                ]
            }
          , { client_id: 2
            , contacts:
                [ { contact_id: 21, name: 'd' }
                , { contact_id: 22, name: 'e' }
                , { contact_id: 23, name: 'f' }
                ]
            }
          , { client_id: 3
            , contacts:
                [ { contact_id: 31, name: 'g' }
                , { contact_id: 32, name: 'h' }
                , { contact_id: 33, name: 'i' }
                ]
            }
          ]
      };
    
    updateClientContact(r.expr(testDoc), 2, 23, { name: 'x', feedback: 'z' });
    

    The result will be

    { clients:
        [ { client_id: 1
          , contacts:
              [ { contact_id: 11, name: 'a' }
              , { contact_id: 12, name: 'b' }
              , { contact_id: 13, name: 'c' }
              ]
          }
        , { client_id: 2
          , contacts:
              [ { contact_id: 21, name: 'd' }
              , { contact_id: 22, name: 'e' }
              , { contact_id: 23, name: 'x', feedback: 'z' } // <--
              ]
          }
        , { client_id: 3
          , contacts:
              [ { contact_id: 31, name: 'g' }
              , { contact_id: 32, name: 'h' }
              , { contact_id: 33, name: 'i' }
              ]
          }
        ]
    }
    

提交回复
热议问题