2012-01-09 44 views
1

考慮下面的文檔結構的結果:CouchDB的 - 重新排序縮小圖

主題:

- doc_type 1 
- _id   
- subject (string) 

帖子:

- doc_type 2 
- _id   
- thread_id (_id of Thread) 
- time  (milliseconds since 1970) 
- comment (string) 

我需要的線程排序由最後發表的帖子,以及最新的5篇文章。 我想避免每次完成一個新帖子時更新線程文檔,以消除跨db節點的分佈式環境中的衝突概率。此外,它將在數據庫應該爲您工作的數據庫中工作。

爲了簡單起見 - 讓我們從查找最新帖子開始。這5個帖子可以採用相同的方式收集。

現在,我不確定我在正確的方向,但是,看起來here我發現如何找到線程中的最後一篇文章,使用reduce函數使用組級別返回線程主題取自doc-type 1,以及從doc-type 2取得的最後一篇文章。

順便說一句 - 與鏈接中的示例相反,在我的情況下,線程始終是用第一個帖子創建的(例如,線程的創建日期將是它的第一個發佈日期)。

圖:

function(doc){ 
    switch(doc.doc_type){ 
    case 1: emit([doc._id],doc); return; 
    case 2: emit([doc.thread_id],doc); return; 
    } 
} 

減少: 上現實世界鍵是多種化合物,所以它必須具有適當的組級別被使用。 爲了簡單起見,我也忽略了重新減少的情況。 你可以找到完整的圖片here

function(keys, vals, rr){ 
    var result = { subject: null, lastPost: null, count :0 }; 
    //I'll ignore the re-reduce case for simplicity 
    vals.forEach(function(doc){ 
     switch(doc.doc_type){ 
     case 1: 
      result.subject = doc.subject; 
      return; 
     case 2: 
      if (result.lastPost.time < doc.time) result.lastPost = doc; 
      result.count++; 
      return; 
     } 
    }); 
    return result; 
} 

但我怎麼頁它後來被最新-發佈日期排序? 有沒有一種方法可以將查詢結果中的doc-id作爲另一個(最好是使用一次往返)的過濾標準來提供?

線程中的帖子數量沒有限制,所以我有點不願意在這裏繼續列表功能,當頁面大小也可能會有所不同時,會導致最後發佈的帖子不會顯示在全部...

有人嗎?

回答

1

如果你只是在最後一篇文章或最後五篇文章之後,有一個更簡單的方法。事實上,你完全可以避免減速器。

如果將時間添加爲密鑰的第二部分,則可以使用endkey,降序和限制的組合來獲取基於thread_id的最後N個帖子。

下面是我根據您的架構一些測試數據寫MapReduce的:

function(doc) { 
    if (doc.type) { 
    if (doc.subject) { 
     emit([doc._id, doc.time], doc.subject); 
     emit([doc._id, 'Z'], doc.subject); 
    } else { 
     emit([doc.thread_id, doc.time], {_id: doc._id}); 
    } 
    } 
} 

的「Z」鍵的怪輸出,讓你獲得從列表中的「底部」的主題項目。

查詢參數看起來是這樣的:

?endkey=["thread_id"]&descending=true&limit=6 

的限制應是N + 1,其中N是你想回的帖子數量。在結果中,您將擁有帖子文檔中的線程主題和_id對象(或任何您想要的)。

在此示例中輸出_id對象,因此如果您要完整發布,可以將其與include_docs=true一起使用。拋棄你想要的任何其他數據(標題等)以保持整體索引尺寸低,並在需要文檔全部內容的地方使用include_docs。但是,如果您始終需要完整的文章文檔,請將其輸出到發佈中,因爲這會爲您提供更快的響應(儘管磁盤上的索引大小更大)。

另外,如果你需要的最後一個職位以及每個線程5個帖子排序的所有線程的列表,你需要輸出鍵,如[time, thread_id, 'thread'][time, thread_id, 'post']並使用_list收集每個線程「下」的帖子文件作爲時間排序將導致線程和帖子在結果中分開。然後可以使用_list功能來再次組合/查找它們。但是,做兩個請求可能仍然更容易/更輕。

+0

我明白如何使用它來檢索給定線程的結果。但我必須在你的回覆中遺漏一些東西 - 我不明白它是如何幫助我獲得最後一篇帖子排序的主題,以及最新的5篇文章:( – 2012-01-31 16:00:11

+0

啊,所以你想要一份清單線程文件(或ID)按最後一篇文章的時間排序?我上面所做的是關注單個線程的文章/ ID如果你需要一個按最後一篇文章排序的所有線程列表,並且每篇文章有5篇線程,你需要輸出諸如[time,thread_id,'thread']和[time,thread_id,'post']之類的鍵並使用_list來收集每個線程文檔下的帖子,因爲時間排序會導致線程並且在結果中帖子會更加分開...... _list可以用來再次組合/查找它們,但是2個請求可能仍然更容易/更輕鬆 – BigBlueHat 2012-02-06 15:58:03

+0

嗯,那就是我害怕的東西最終我來到了相同的地方結論,但是要尋求專家的意見,也許有一種方法可以重用ID的查詢輸出作爲input-filt呃的觀點,而不是在兩個請求做......如果你更新你的答案與你在評論中說 - 我只是可能接受它:) – 2012-02-14 08:28:46