RethinkDB:​​数组的实时更改,return 仅新添加

RethinkDB: Realtime Changes On Array, return only newly appended

简介:我正在使用 RethinkDB 的更改提要来查看特定文档(不是整个 table)的更改。每条记录如下所示:

{
  "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 的变化array... 然后做一些事情(具体来说,仅通过 websockets 广播附加到反馈 的 最后一项)。我已经将它连接起来,以便它可以监视整个文档的更新 - 但是,它需要接收 complete 文档,然后只获取反馈数组中的最后一项。这感觉太重了,当我需要返回的是最后添加的东西时。

当前用于更新文档的代码:

r.table('myTable').get(uuid)
.update({feedback:r.row('feedback').append('message 1')})
.run(conn, callback)(...}

^ 这将在一分钟左右的时间内多次 运行,将最新消息添加到 'feedback'。

正在观察变化:

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

最后,这是问题(实际上是 2 个部分):

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: When I'm updating the document (adding to feedback), do I have to run an update on the entire document (as in my code above),

不,你不知道。正如您所做的,您只更新 feedback 字段。不完全是文档,不是吗?

or is it possible to simply append to the feedback array and be done with it?

这是可能的。而且你已经做到了。

它的编写方式看起来您的客户端驱动程序必须获取 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 查询是通过网络传输的,而不是整个文档。希望这是有道理的。有关 JSON 字符串的更多信息,请访问 http://rethinkdb.com/docs/writing-drivers/ and https://github.com/neumino/rethinkdbdash/blob/master/lib/protodef.js#L84

2: Is the way I'm doing it above (receiving the entire document and plucking the last element from feedback array) the only way to do this? Or can I do something like:

理想情况下,我们希望使用括号来获取文档的字段,并监听该字段的变化。不幸的是它还没有用。所以我们要用map来改造一下。同样,这个 运行 在服务器上并且只有最后一个文档传输到客户端,而不是整个文档:

r.table('myTable').get(1).changes().map(function(doc) {
  return doc('new_val')('feedback').default([]).nth(-1)
})