1

I have a table that contains complex nested documents. The structure of each document is similar to the following example:

{
  "description": "Sample Document",
  "events": [
    {
      "liquids": { ... },
      "protocol": {
        "id": "5b190c4d-6590-49a3-b9a7-69f036f45e55"
      },
      "schedule": { ... }
    },
    {
      "liquids": { ... },
      "protocol": {
        "id": "a4353a88-6021-418f-a18c-0526550edb57",
        "overrides": [
          {
            index: 9,
            values:  {
              foo: "bar"
            }
          {
            index: 7,
            parentIndex: 10,
            values: {
              foo: 8,
              bar: 9
            }
          }
        ]
      },
      schedule: { ... }
    }
  ],
  "id": "7c424fc3-1a58-4a4e-b1b6-8d25412a85da",
  "name": "Sample Doc",
  "project_id": "__ROOT__"
}

I want to update one of the items in the protocol.overrides property of the second item in the events array. I know ahead of time that I need to access myTable.get($id).events(1)('protocol')('overrides') but I have no way of knowing ahead of time which item in the nested array that I need to replace.

In this specific example, lets say that I need to replace the item with index: 7, and parentIndex: 10 (the second item) and lets say that I want to change its values property to {foo: "baz", bar: "curley"}.

I don't see any methods in the reQL API that let me do this. changeAt can be used if I know the array index, but I don't see an indexOf function or anything similar that lets me find the index by matching a predicate.

1 Answer 1

1

Assuming I understand what exactly you're asking for, including what data is known and what should be queried by it (if not, tweak it), this is how I'd do it:

myTable.get($id) 
  .update(function(row) {
    return {
      events: row('events').map(function(event) {
        return r.branch(
          event('protocol')('overrides').default([]).filter({index: 7}),
          event.merge({
            protocol: {
              overrides: event('protocol')('overrides').default([])
              .map(function(override) {
                return r.branch(
                  override('index').eq(7),
                  override.merge({
                    values: {
                      foo: "baz",
                      bar: "curley"
                    }
                  }),
                  override
                )
              })
            }
          }),
          event
        )
      })
    }
  })

I'm using:

  • .update() method directly on row/s and not on nested data
  • r.branch() for conditions

Not sure this is the best practice, but it seems like it gets the job done.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.