简介:我正在使用RethinkDB的更改源来观察特定文档(而不是整个表)的更改。每条记录都是这样的:
{
"feedback": [ ],
"id": "bd808f27-bf20-4286-b287-e2816f46d434" ,
"projectID": "7cec5dd0-bf28-4858-ac0f-8a022ba6a57e" ,
"timestamp": Tue Aug 25 2015 19:48:18 GMT+00:00
}
我有一个进程将项目附加到 feedback 数组,另一个进程需要监视 feedback 数组中的更改...然后执行某些操作(具体而言,仅通过websockets广播最后一项附加到反馈)。我已将它连接起来以便监视整个文档的更新 - 但是,它需要接收完整的文档,然后只获取反馈数组中的最后一项。当我需要回来的是最后添加的东西时,这感觉过于沉重。
用于更新文档的当前代码:
r.table('myTable').get(uuid)
.update({feedback:r.row('feedback').append('message 1')})
.run(conn, callback)(...}
^这将在一分钟左右的时间内运行几次,将最新消息添加到“反馈”。
观看更改:
r.table('myTable').get(uuid)
.changes()
.run(conn, function(err, cursor){
cursor.each(function(err, row){
var indexLast = row.old_val ? row.old_val.feedback.length : 0,
nextItem = row.new_val.feedback[indexLast];
// ... do something with nextItem
})
})
最后,这是问题(真的是两部分):
1:当我更新文档时(添加反馈),我是否必须在整个文档上运行update
(如上面的代码所示),或者是可以简单地附加到反馈数组并完成它吗?
2:我上面这样做的方式(接收整个文档并从反馈数组中取出最后一个元素)是唯一的方法吗?或者我可以这样做:
r.table('myTable').get(uuid)
.changes()
.pluck('feedback').slice(8) // <- kicking my ass
.run(conn, function(err, cursor){
cursor.each(function(err, row){
var indexLast = row.old_val ? row.old_val.feedback.length : 0,
nextItem = row.new_val.feedback[indexLast];
// ... do something with nextItem
})
})
答案 0 :(得分:3)
让我们回顾一下你的问题
1:当我更新文档时(添加反馈), 我是否必须对整个文档进行更新(如上面的代码所示),
不,你没有。正如您所做的那样,您只更新了feedback
字段。不是完整的文件,不是吗?
或者是否可以简单地附加到反馈数组并完成它?
这是可能的。你已经做到了。
它的写入方式看起来像您的客户端驱动程序必须获取feedback
数组的内容,然后附加一个新元素,并更新整个内容。但事实并非如此。整个查询r.row('feedback').append('message 1')
被序列化为JSON字符串并传递给RethinkDB。 RethinkDB在服务器上以原子方式运行它。 feedback
的内容和附加内容不在客户端上完成,也不会发送回服务器。
如果您使用tcpdump
,请执行以下操作:
tcpdump -nl -w - -i lo0 -c 500 port 28015|strings
运行查询时,您可以看到此JSON字符串是RethinkDB服务器的发件人:
[1,[53,[[16,[[15,["myTable"]],1]],[69,[[2,[3]],{"feedback":[29,[[170,[[10,[3]],"feedback"]],"doc2"]]}]]]],{}]
是的,单个JSON查询是通过网络传输的,而不是整个文档。希望它有意义。可以在http://rethinkdb.com/docs/writing-drivers/和https://github.com/neumino/rethinkdbdash/blob/master/lib/protodef.js#L84
上找到有关该JSON字符串的更多信息2:我上面这样做的方式(接收整个文档并从反馈数组中取出最后一个元素)是唯一的方法吗?或者我可以这样做:
理想情况下,我们希望使用括号来获取文档字段,并监听该字段的更改。不幸的是它还没有用。所以我们必须使用map
来转换它。同样,这在服务器上运行,只有最后一个文档传输到客户端,而不是整个文档:
r.table('myTable').get(1).changes().map(function(doc) {
return doc('new_val')('feedback').default([]).nth(-1)
})