2008-11-23 27 views
42

我將如何去執行分頁所需的查詢?分頁在CouchDB?

基本上,當請求頁面1時,得到前5個條目。對於第2頁,獲取下一個5等等。

我打算通過couchdb-python模塊來使用它,但是這對實現沒有任何影響。

回答

31

CouchDB Guide具有分頁的一個很好的討論,其中包括大量的示例代碼,在這裏:http://guide.couchdb.org/draft/recipes.html#pagination 這裏是他們的算法:

  • 請求從視圖rows_per_page + 1
  • 顯示rows_per_page行,店最後一排爲next_startkey
  • 至於頁面信息,請保留startkeynext_startkey
  • 使用next_*個值以創建下一個鏈接,並使用他人創建一個鏈接

N.B:抓取網頁的正確方法CouchDB中是通過指定起始關鍵,而不是像你這樣的起始索引的想象。但你怎麼知道開始第二頁的關鍵?聰明的解決方案:「不要求爲一個頁面請求10行,而是請求11行,但只顯示10行,並使用第11行中的值作爲下一頁的啓動鍵。」

如果您希望多個文檔發出相同的密鑰,則除了startkey之外,還需要使用startdocid才能正確分頁。原因是僅僅startkey將不再足以唯一地標識一行。如果您沒有提供startkey,那些參數是無用的。事實上,CouchDB將首先查看startkey參數,然後它將使用startdocid參數來進一步重新定義範圍的開始,如果多個潛在起始行具有相同的密鑰但不同的文檔ID。 同樣的事情。

1

這就是我想出了這麼遠 - 讓所有帖子的ID,然後檢索ID的前X個實際項目..

這不是非常有效的,但更多的比檢索所有的帖子,然後扔掉大部分。這就是說,令我驚訝的是,它似乎運行得非常快 - 我運行了posthelper.page()方法100次,耗時約0.5秒。

我不想在實際問題張貼此,所以它沒有那麼多影響答案 - 這裏是代碼:

allPostsUuid = """ 
function(doc) { 
if(doc.type == 'post'){ 
    emit(doc._id, null); 
} 
} 
""" 

class PostsHelper: 
    def __init__(self): 
     server = Server(config.dbhost) 
     db = server[config.dbname] 
     return db 


    def _getPostByUuid(self, uuid): 
     return self.db.get(uuid) 

    def page(self, number = 1): 
     number -= 1 # start at zero offset 
     start = number * config.perPage 
     end = start + config.perPage 

     allUuids = [ 
      x.key for x in self.db.query(allPostsUuid) 
     ] 
     ret = [ 
      self._getPostByUuid(x) for x in allUuids[start : end] 
     ] 

     if len(ret) == 0: 
      raise Error404("Invalid page (%s results)" % (len(allUuids))) 
     else: 
      return ret 
13

CouchDB的HTTP View API提供了大量的範圍,以有效地完成分頁。

最簡單的方法將使用startkeycount。 Count是CouchDB將針對該視圖請求返回的最大條目數,這取決於您的設計,startkey是您希望CouchDB啓動的位置。當您請求視圖時,它還會告訴您有多少條目,從而可以計算出要顯示給用戶的頁數。

因此,第一個請求不會指定startkey,只是您要顯示的條目數的計數。然後您可以記下返回的最後一個條目的關鍵字,並將其用作下一頁的開始鍵。在這種簡單的表格中,您將看到重疊,其中一頁的最後一項是下一項的第一項。如果這不是所希望的,則簡單地不顯示頁面的最後一個條目是微不足道的。

這樣做的一個簡單方法是使用skip參數來計算頁面的起始文檔,但應謹慎使用此方法。 skip參數只是簡單地導致內部引擎不返回正在迭代的條目。雖然這給出了所需的行爲,但它比按鍵查找頁面的第一個文檔要慢很多。跳過的文檔越多,請求越慢。

+0

啊哈!從該頁面鏈接:count參數可以與「跳過=要跳過的行數」組合。完善。 – dbr 2008-11-25 09:06:15

+0

我已將上述信息添加到您的答案(如果沒有其他內容,請參閱我的參考資料),希望您不介意! – dbr 2008-11-25 09:24:33