RethinkDB - 是否有更好的方法在嵌套数组上执行此非原子更新?

RethinkDB - is there a better way of doing this non-atomic update on a nested array?

我在 RethinkDB 数据库中有两个表 - "leagues" 和 "players",文档结构如下:

玩家

{
  id: 1,
  name: "Bob",
  email: "bob@bob.com"
}

联赛

{
  id: 1,
  name: "L1",
  standings: [{
    "player_id": 1,
    "position": 1
  },{
    "player_id": 2,
    "position": 2
  }]
}

我想要实现的是当玩家被删除时,有一个明显简单的 ReQL 查询来删除玩家:

r.table("players").get(1).delete().run(conn, callback);

但我还需要将该球员从他们正在参加的任何联赛中移除,然后更新该联赛中所有其他球员的位置,以便他们再次成为连续的。

这是我必须删除 ID 为“2”的玩家的查询:

r.table("leagues").getAll(2, { index: "player_id" }).update({
  standings: r.row("standings").filter(function(standing) {
    return standing("player_id").ne(2)
  }).map(function(standing) {
    return r.branch (
      standing("position").gt(
        r.table("leagues").getAll(2, { index: "player_id" }).nth(0)("standings").filter(function(s) {
            return s("player_id").eq(2)
            }).nth(0)("position")
      ),
      standing.merge({ position: standing("position").sub(1) }),
      standing
    )
  })
}, {
  nonAtomic: true 
})

这是有效的,它删除了被删除的玩家,然后洗牌剩余玩家的位置以填补空白并再次成为连续的。

我的问题是,有没有更好的方法?一个我不必将查询指定为非原子的?我只能认为我需要首先进行一些单独的查询,以找到我想要删除的玩家的位置,这样就可以将其作为变量而不是子查询传递,因为我相信这就是那部分正在使它成为非原子的。

干杯

我假设排名总是与数组中的位置匹配?

如果是这样,你可以这样写:

r.table('leagues').getAll(2, {index: 'player_id'}).update(function(row) {
  return {
    standings: row('standings').filter(function (standing) {
      return standing('player_id').ne(2);
    }.map(r.range(), function(standing, index) {
      return standing.merge({position: index.add(1)});
    })
  };
});

如果没有,你可以这样写:

r.table('leagues').getAll(2, {index: 'player_id'}).update(function(row) {
  return row('standings').filter(function (standing) {
    return standing('player_id').eq(2);
  }).nth(0)('position').do(function(pos) {
    return {
      standings: row('standings').filter(function (standing) {
        return standing('player_id').ne(2);
      }).map(function(standing) {
        return r.branch(
          standing('position').gt(pos),
          standing.merge({position: standing('position').sub(1)}),
          standing);
      })
    };
  });
});

{ 排名:行('standings').filter(函数(站立){ return 站立('player_id').ne(2) }.map(r.range(), function(standing, index) { return standing.merge({位置: index.add(1)}); }) }; })