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的。