RethinkDB:​​对数组进行实时更改,仅返回新附加的

时间:2015-08-25 20:20:50

标签: rethinkdb real-time-updates rethinkdb-javascript

简介:我正在使用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
  })
})

1 个答案:

答案 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)
})