1

在查看了 RethinkDB github 上的一些 SO 问题和问题后,我没有得出一个明确的结论,如果原子 Upsert 是可能的?

本质上,我想使用 Redis 执行与 ZINCRBY 相同的操作。

如果成员在排序集中不存在,则将其添加为增量作为其分数(就像它之前的分数是 0.0)。如果 key 不存在,则创建一个以指定成员为唯一成员的新排序集。

当前的实现似乎与我使用过的几乎所有数据库都不同。被替换或插入的数据未更新。这是一个简单的用例,例如更新上次访问、更新点击次数、更新产品数量。所以我一定错过了一些非常明显的东西,因为我看不到一个简单的方法来做到这一点。

4

2 回答 2

1

对的,这是可能的。上键后get,执行原子replace. 像这样的东西可能会起作用:

function set_or_increment_score(player, points){
  return r.table('scores').get(player).replace(
    row =>
      { id: player,
        score: r.branch(
                 row.eq(null),
                 points,
                 row('score').add(points))
      });
}

它具有以下行为:

> set_or_increment_score("alice", 1).run(conn)
{ inserted: 1 }
> set_or_increment_score("alice", 2).run(conn)
{ replaced: 1 }

它之所以起作用,是因为当文档不存在时get返回,并且不存在的文档上的 a 转换为插入。请参阅替换文档nullreplace

于 2016-11-01T20:04:45.587 回答
0

所以我最终使用以下代码来解决无更新问题。

r.db("test").table("t").insert(
  {id:"A", type:"player", species:"warrior", score:0, xp:0, armor:0},
  {conflict: function(id, oldDoc, newDoc) {
       return newDoc.merge(oldDoc).merge(
         {armor: oldDoc("armor").add(1)});
   }
  }
)

您认为这是否更具可读性/优雅,或者与您的示例相比,您是否发现代码有任何问题?

于 2016-11-03T11:54:03.737 回答