使用RethinkDB正确Upsert(原子更新计数器字段或插入文档)

时间:2016-11-01 16:48:50

标签: rethinkdb rethinkdb-javascript

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

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

  

如果已排序集中不存在成员,则会添加增量   作为其分数(好像它以前的分数是0.0)。如果键没有   存在,一个新的有序集合,其中指定的成员作为其唯一成员   已创建。

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

2 个答案:

答案 0 :(得分:1)

是的,有可能。在密钥上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

这是有效的,因为null在文档不存在时返回replace,并且不存在的文档上的r = requests.get('https://jsonplaceholder.typicode.com/posts') print(r) print(r.headers) print(r.encoding) data = r.json() log.debug(data) log.debug(r) for post in data: s = format(post["id"],post['title']) 会调入插入内容。请参阅documentation for replace

答案 1 :(得分: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)});
   }
  }
)

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