2

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

我有一个进程将项目附加到反馈数组,另一个进程需要观察反馈数组的变化......然后做一些事情(具体来说,只广播通过 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
  })
})
4

1 回答 1

4

让我们回顾一下你的问题

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 查询是通过网络传输的,而不是整个文档。希望这是有道理的。有关该 JSON 字符串的更多信息,请参见http://rethinkdb.com/docs/writing-drivers/https://github.com/neumino/rethinkdbdash/blob/master/lib/protodef.js#L84

2:我在上面做的方式(接收整个文档并从反馈数组中提取最后一个元素)是唯一的方法吗?或者我可以做类似的事情:

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

r.table('myTable').get(1).changes().map(function(doc) {
  return doc('new_val')('feedback').default([]).nth(-1)
})
于 2015-08-25T21:05:51.877 回答