2017-10-17 68 views
0

我试图根据branch条件对数组字段进行简单的upsert操作。但是branch不接受reql表达式作为参数,我得到错误Expected type SELECTION but found DATUM如何使用RethinkDB中的分支有条件地更新项目

这可能是我错过的一些显而易见的事情,但我无法在任何地方找到任何工作示例。

样品来源:

var userId = 'userId'; 
var itemId = 'itemId'; 

r.db('db').table('items').get(itemId).do(function(item) { 

    return item('elements').default([]).contains(function (element) { 
    return element('userId').eq(userId); 
    }).branch(

    r.expr("Element already exist"), 

    //Error: Expected type SELECTION but found DATUM 
    item.update({ 
     elements: item('elements').default([]).append({ 
     userId: 'userId' 
     }) 
    }) 
) 
}) 

回答

1

这里的问题是,item为基准,而不是一个选择。发生这种情况是因为您使用了r.do。该变量不保留关于对象最初来自何处的信息。

似乎可行的解决方案是编写新的r.db('db').table('items').get(itemId)表达式。该选项的问题是行为不是原子的 - 两个不同的查询可能会将相同的元素添加到“元素”数组中。相反,您应该以r.db('db').table('items').get(itemId).update(function(item) { return <something>;)的形式编写查询,以便更新以原子方式应用。

+0

非常感谢@ sam-hughes。我仍然怀疑这样的交易是否可以以最佳方式完成。据我所知 - 它需要做两个截然不同的非原子请求或总是进行更新。 – xb1itz

+0

@ xb1itz - 更新将以最佳方式进行。如果更新返回相同的文档,保持不变,则不会写入任何内容。 RethinkDB专门将新版本的文档与旧版本进行比较。如果你对此感到紧张,我想你也可以使用r.error来中止更新。 –

相关问题