查询在不知道索引的情况下更新嵌套数组项

Query to update nested array item without knowing the index

我有一个 table,其中包含复杂的嵌套文档。每个文件的结构类似于下面的例子:

{
  "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__"
}

我想更新 events 数组中第二项的 protocol.overrides 属性 中的一项。我提前知道我需要访问 myTable.get($id).events(1)('protocol')('overrides') 但我无法提前知道我需要替换嵌套数组中的哪个项目。

在这个具体示例中,假设我需要用 index: 7parentIndex: 10(第二项)替换该项目,假设我想更改其 values 属性 到 {foo: "baz", bar: "curley"}.

我在 reQL API 中没有看到任何方法可以让我这样做。如果我知道数组索引,可以使用 changeAt,但我没有看到 indexOf 函数或任何类似的东西,可以让我通过匹配谓词找到索引。

假设我理解您的确切要求,包括哪些数据是已知的以及应该查询哪些数据(如果不是,请对其进行调整),这就是我的做法:

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

我正在使用:

  • .update() 方法直接在 row/s 而不是嵌套数据
  • r.branch() 条件

不确定这是最佳做法,但似乎可以完成工作。