mik*_*ana 4 javascript node.js rethinkdb
我知道rethinkDB 的 insert()有一个 upsert 选项。例如,来自文档:
rethinkdb.table('marvel').insert(
{ superhero: 'Iron Man', superpower: 'Arc Reactor' },
{upsert: true, return_vals: true}
).run(conn, callback)
Run Code Online (Sandbox Code Playgroud)
但是说可能存在{superhero: 'Iron Man'}不正确或过时的超级大国的现有记录,并且我想插入{ superhero: 'Iron Man', superpower: 'Arc Reactor' }或更新任何现有{superhero: 'Iron Man'}记录?
简而言之:如何更新插入以便仅在匹配特定字段时更新现有记录?
编辑:似乎这是用 .replace() 完成的:
如果对不在表中的键进行点替换,则可以插入新文档
我不确定“点替换”是什么意思 - 但我认为它只是意味着替换。
var latestDoc = { superhero: 'Iron Man', superpower: 'Arc Reactor' }
var mergeOrCreate = function(existingDoc) {
if ( existingDoc ) {
return existingDoc.merge(latestDoc)
} else {
return latestDoc
}
}
rethinkdb.table('marvel')
.filter({ superhero: 'Iron Man'})
.replace(mergeOrCreate),
).run(conn, callback)
Run Code Online (Sandbox Code Playgroud)
然而,在测试中,'mergeOrCreate' 函数被赋予另一个函数作为参数,而不是实际的文档或游标。
您的第一个代码块是您的第一个问题的答案。但是,它假定这superhero是您的表的主键。
创建表时可以设置表的主键:
r.tableCreate('marvel', {primaryKey: 'superhero'}).run(conn, cb)
Run Code Online (Sandbox Code Playgroud)
你的第二个代码块有两个错误。
首先,mergeOrCreate 函数不起作用,因为if语句是在客户端计算的。您必须使用r.branch来创建等效的if语句:
var mergeOrCreate = function(existingDoc) {
return r.branch(existingDoc, /* if */
existingDoc.merge(latestDoc), /* then */
latestDoc) /* else */
}
Run Code Online (Sandbox Code Playgroud)
其次,get不支持与filter. 它的参数应该是主键的值。如果主键是superhero,则:
r.table('marvel')
.get('Iron Man')
Run Code Online (Sandbox Code Playgroud)
最后,如果superhero不是主键,则必须编写不同类型的查询。可能有零个、一个或多个具有相同superhero. 这是一种写法:
r.table('marvel')
.insert(
r.table('marvel')
.filter({ superhero: 'Iron Man' })
.coerceTo('array')
.do(function(docs){
return r.branch(
docs,
docs.merge(latestDoc),
latestDoc)
}),
{ upsert: true })
.run(conn, cb);
Run Code Online (Sandbox Code Playgroud)
请注意,由于此查询依赖于多个文档,因此它不是原子的。
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |