RethinkDB:条件upsert(只有当特定的字段匹配)?
我知道rethinkDB的insert()有一个upsert选项。 例如,从文档:
rethinkdb.table('marvel').insert( { superhero: 'Iron Man', superpower: 'Arc Reactor' }, {upsert: true, return_vals: true} ).run(conn, callback)
但是可以说,对于超级大国来说, 可能有{superhero: 'Iron Man'}
logging,我想要插入{ superhero: 'Iron Man', superpower: 'Arc Reactor' }
或更新任何现有的{superhero: 'Iron Man'}
战绩?
简而言之:我如何插入,以便现有logging只有在特定字段匹配时才会更新?
编辑:似乎这是用.replace()完成的:
以下是replace()文档中的重要部分:
如果您对不在表格中的键进行点replace,则可以插入新的文档
我不确定“点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)
然而在testing中,'mergeOrCreate'函数被赋予另一个函数,而不是实际的文档或游标作为参数。
你的第一个代码块是你的第一个问题的答案。 不过,它假定superhero
是你的表的主键。
创build表时可以设置表的主键:
r.tableCreate('marvel', {primaryKey: 'superhero'}).run(conn, cb)
你的第二个代码块有两个错误。
首先,mergeOrCreate函数不起作用,因为if
语句被评估客户端。 您必须使用r.branch
创build一个if
语句的等价物:
var mergeOrCreate = function(existingDoc) { return r.branch(existingDoc, /* if */ existingDoc.merge(latestDoc), /* then */ latestDoc) /* else */ }
其次, get
不支持与filter
相同的语法。 它的论点应该是主键的价值。 如果主键是superhero
,则:
r.table('marvel') .get('Iron Man')
最后,如果superhero
不是主键,你必须写一个不同types的查询。 可能有零,一个或多个文件与同一个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);
请注意,因为这个查询依赖于多个文档,所以它不是primefaces的。