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
}

フィードバック配列にアイテムを追加するプロセスが1つあり、フィードバック配列の変更を監視する必要がある別のプロセスがあります...そして何かを行います(具体的には、フィードバックに最後に追加されたアイテムのみをwebsockets経由でブロードキャストします)。ドキュメント全体の更新を監視するように配線しましたが、完全なドキュメントを受信して​​から、フィードバック配列の最後の項目だけを取得する必要があります。戻す必要があるのは最後に追加されたものだけである場合、これは過度に重く感じます。

ドキュメントの更新に使用される現在のコード:

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

^ これは 1 分程度の間に数回実行され、最新のメッセージが「フィードバック」に追加されます。

変更の監視:

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
  })
})
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 に答える