查询更新嵌套数组项而不知道索引

时间:2017-01-06 21:38:37

标签: rethinkdb reql nosql

我有一个包含复杂嵌套文档的表。每个文档的结构类似于以下示例:

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

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

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

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

1 个答案:

答案 0 :(得分:1)

假设我明白你究竟要求的是什么,包括知道什么数据以及它应该查询什么(如果没有,调整它),我就是这样做的:

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

我正在使用:

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

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