在 RethinkDB 中获取两个流差异的有效方法

Efficient way to get difference of two streams in RethinkDB

我是 运行 RethinkDB 的一些性能基准(与特定用例相关)。在我的模拟中,有 2 个 table:contactevent。一个联系人有很多事件。事件 table 有 2 个索引:contact_id 和 [campaign_id, node_id, event_type] 上的复合索引。 contact table 在 event table.

中有大约 50 万个联系人和大约 175 万个文档

我遇到的问题是查找所有拥有 sent event_type 但没有 open event_type 的联系人。以下是我开始工作的查询:

r.table("events"). get_all([1, 5, 'sent'], {index: 'campaign'})['contact_id'].distinct .set_difference (r.table("events").get_all([1, 5, 'open'], {index: 'campaign'})['contact_id'].distinct) .count.run(conn)

但是这个查询使用的是set difference,不是stream difference。我也尝试过使用 difference operator:

r.table("events"). get_all([1, 5, 'sent'], {index: 'campaign'})['contact_id'] .difference (r.table("events").get_all([1, 5, 'open'], {index: 'campaign'})['contact_id']) .count.run(conn)

这个查询永远不会完成,奇怪的是即使在我看到(在 RethinkDB 仪表板中)中止查询后,读取也不会停止。

执行此类查询的最有效方法是什么?

跟进:找到所有 sent event_type 但没有 open event_type 的男性联系人。我现在拥有的是:

r.table("contacts").get_all(r.args( r.table("events").get_all([1, 5, 'sent'], {index: 'campaign'})['contact_id'].distinct .set_difference (r.table("events").get_all([1, 5, 'open'], {index: 'campaign'})['contact_id'].distinct))) .filter({gender: 1}).count.run(conn)

提高效率的一种方法是对数据进行非规范化。不用单独的 contactevent table,只需 contact table 并使每个 contact 都有一个事件数组。然后你可以写:

r.table('contacts').indexCreate('sent_but_not_open', function(row) {
  return row('events').contains('sent').and(
    row('events').contains('open').not());
});

如果每个联系人的事件数量很少,那将很有效。如果每个联系人有数千或数百万个事件,它就会崩溃。

RethinkDB 不提供在服务器上延迟区分两个流的方法。您可以做的最好的事情是将复合索引更改为 [campaign_id, node_id, event_type, contact_id],将 get_all([1, 5, 'sent'], {index: 'campaign'}) 替换为 .between([1, 5, 'sent', r.minval], [1, 5, 'sent', r.maxval], {index: 'campaign'})and then put.distinct({index: 'campaign'})['contact_id']on the end. That will give you a stream of distinct contact IDs rather than an array, and these contact IDs will be sorted. You can then do the same for theopen` 事件,并通过执行类似合并排序的操作来区分客户端中的两个有序流。