2016-01-05 30 views
2

在RethinkDB中,我需要在兩個表之間執行連接(表示has-and-belongs-to-many關係),然後對連接的結果進行排序。可能有數十萬甚至數百萬的結果,所以我需要對它們進行有效的分類。有沒有一種有效的方法來對RethinkDB中的連接結果進行排序?

理想情況下,我想用索引orderBy()。但是orderBy() can only use an index when called on a table.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()開始變得太慢時,主題包含了幾千年的對話,並會在100,000徹底打破由於RethinkDB的數組大小限制。這個數據庫中的主題很容易包含數十萬甚至數百萬次的對話,所以這是不可接受的。

我只需要這個查詢一次返回一小部分結果(比如說25),但我需要這些結果才能排序,所以我不能限制,直到排序後。有任何想法嗎?

回答

2

我認爲另一種方法是刪除conversations_topics並將主題數據嵌入到conversations表中。用這個我們可以創建一個複合索引,然後用它們同時做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來實現更快的速度。

希望它會更快。

相關問題