在 RethinkDB 中是否有一种有效的方法来对连接的结果进行排序?

Is there an efficient way to sort the results of a join in RethinkDB?

在 RethinkDB 中,我需要在两个表之间执行一个连接(表示一个 has-and-belongs-to-many 关系),然后对连接结果进行排序。可能有数十万甚至数百万个结果,因此我需要对它们进行高效排序。

理想情况下,我想将 orderBy() 与索引一起使用。但是orderBy() can only use an index when called on a table, and .eqJoin() returns a stream or an array.

这是我正在使用的查询示例。我想获取具有给定主题的对话:

r.table('conversations_topics')
  .getAll('c64a00d3-1b02-4045-88e7-ac3b4fee478f', {index: 'topics_id'})
  .eqJoin('conversations_id', r.table('conversations'))
  .map(row => row('right'))
  .orderBy('createdAt')

当一个主题包含几千个对话时,此处使用的未索引 orderBy() 开始变得慢得令人无法接受,并且由于 RethinkDB 的数组大小限制,将在 100,000 时完全中断。此数据库中的主题很容易包含数十万甚至数百万个对话,因此这是不可接受的。

我一次只需要此查询 return 少量结果(比如 25),但我需要按顺序排列这些结果,因此在排序后才能限制。有什么想法吗?

我认为另一种方法是删除 conversations_topics 并将主题数据嵌入 conversations table。这样我们就可以创建一个复合索引,然后使用 between 来同时做 filterorder

r.table('conversations').indexCreate('topicAndDate', function(doc) {
  return doc('topics')
    .map(function(topic) {
      return [topic, doc('createdAt')]
    })
    .coerceTo('array')
}, {multi: true})

然后你可以像这样查询:

r.table('conversations').between([('c64a00d3-1b02-4045-88e7-ac3b4fee478f', r.minval], [('c64a00d3-1b02-4045-88e7-ac3b4fee478f', r.maxval], {index: 'topicAndDate'})
  .orderBy({index: r.desc('topicAndDate')})
  .limit(25)

这里的关键是我们对 orderBybetween 使用相同的索引。如果你知道时间范围,通过在 between 命令中设置时间值而不是使用 minvalmaxval.

可以使速度更快

希望能快点。