在 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 来同时做 filter
和 order
。
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)
这里的关键是我们对 orderBy
和 between
使用相同的索引。如果你知道时间范围,通过在 between
命令中设置时间值而不是使用 minval
和 maxval
.
可以使速度更快
希望能快点。
在 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 来同时做 filter
和 order
。
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)
这里的关键是我们对 orderBy
和 between
使用相同的索引。如果你知道时间范围,通过在 between
命令中设置时间值而不是使用 minval
和 maxval
.
希望能快点。