假设我有一份文件
{
id: 1,
fruits: []
}
这里的水果充当了SET
现在我希望原子为fruits数组添加一个值,使用primary key = 1 OR 创建这样的文件(如果它不存在)(即使用SetInsert ReQL)引擎盖)
我还需要为增量(ReQL .Add)
做同样的事情显然这不能在客户端代码中完成,因为它打破了原子性,最终导致数据不一致
我希望这样的事情可能
r.table('results').insert({
id: '62c70132-6516-4279-9803-8daf407ffa5c',
counter: r.row('counter').add(1).default(0)
}, {conflict: "update"})
但它死于“RqlCompileError:r.row未在此上下文中定义”
感谢任何帮助/指导, 谢谢!
答案 0 :(得分:7)
目前insert
无法做到这一点。另一个提到的解决方案不是原子的,因为它使用子查询。
我们正在https://github.com/rethinkdb/rethinkdb/issues/3753中为此制定解决方案。
但是,您可以使用replace
执行原子upsert:
r.table('results').get('62c70132-6516-4279-9803-8daf407ffa5c')
.replace({
id: '62c70132-6516-4279-9803-8daf407ffa5c',
counter: r.row('counter').add(1).default(0)
})
如果文档不存在, replace
将实际执行插入。
答案 1 :(得分:3)
在RethinkDB中,所有单一查询更新都是原子的。如果Rethink认为特定的更新/替换操作不是原子的,则会抛出错误并要求您向查询添加非原子标记。通常情况下,您不必过于担心它。但是,仅适用于update
和replace
个查询。使用insert
原型无法做到这一点。
你是正确的,如果您检索该文档,请更新它的客户端,然后将其放回到数据库中,它本质上也是非原子更新。
但是,在单个查询中,您可以执行以下操作,这与您使用insert
的方式相同,但使用replace
:
r.table('FruitStore')
.get(1)
.replace({
id : 1,
fruits : r.row('fruits').default([]).append('orange')
})
......这将是原子的。同样,要使用添加操作:
r.table('FruitStore')
.get(1)
.replace({
id : 1,
count : r.row('count').default(0).add(1)
})