2010-12-13 104 views
1

這是我在stackoverflow上的第一個問題,所以我希望我遵循正確的協議。我可以通過常用密鑰訂購CouchDB文檔嗎?

我正在創建基於CouchDB和NodeJS的基本瀏覽器遊戲。在我的遊戲中,用戶可以有多個角色。我決定將玩家與他們的數據庫中的角色分開,因爲我很少需要將用戶帳戶數據(電子郵件,真實姓名等)與角色數據相關聯。無論如何,這是我的問題:

我希望能夠創建一個視圖,返回由玩家控制的所有角色。本文檔中將會有一個名爲「所有者」的屬性。我認爲最簡單的方法是製作一個視圖,它返回所有由所有者分類的字符的列表。

這裏是我到目前爲止的代碼:

功能(DOC){ EMIT(doc.owner,DOC); }

我想要得到這樣的結果(注意,這是簡化的,我知道的CouchDB在輸出中包括其他數據):

{ 
    "player1":{ 
     "character1":{ 
      "data":{} 
     }, 
     "character2":{ 
      "data":{} 
     } 
    }, 
    "player2":{ 
     "character1":{ 
      "data":{} 
     }, 
     "character2":{ 
      "data":{} 
     } 
    } 
} 

難道鍵必須是唯一的?我的代碼會給我想要的結果嗎?

我沒有想過分離數據的想法,我可以選擇將字符放在用戶文檔的下方,然後創建兩個視圖,一個只發出用戶帳戶數據並忽略字符數據,另一個只發送字符數據並省略用戶數據,但這對我來說似乎有些尷尬。我寧願將數據分開,因爲我可能需要編寫其他特定於角色數據的視圖,而且如果我將角色與數據庫中的角色分開,似乎會更好地組織起來。

在相關說明中,是否有任何方法通過傳遞第二個參數來過濾響應?我認爲這會否定視圖的效率,我應該在這種情況下使用臨時視圖。我的問題是我可能會有大量的數據被這個視圖返回(實際上是整個數據庫),當通過HTTP傳輸時,這可能會非常緩慢,特別是因爲我不需要大部分數據。

另一種可能的解決方案是將用戶控制的每個字符的_id作爲屬性存儲在用戶帳戶數據庫中。這對我來說似乎足夠明智,但如果有不同,或者我敢說「更好」選項可用,那麼我很樂意聽到它。

這是什麼問題的最佳解決方案?

非常感謝您的幫助。

+0

哇,你的第一個問題,現在你是10K + :) ... – TimoSolo 2016-11-25 10:32:10

回答

4

你在正確的道路上。如果您希望與減少要做到這一點,你可以定義此地圖:

function(doc) { 
    var r = {}, c = {}; 
    c[doc._id] = doc; 
    r[doc.owner] = c; 
    emit(doc.owner,r); 
} 

這降低:

function(k,v,red) { 
    var r = {}; 
    for (var i in v) { 
    for (var owner in v[i]) { 
     if (!(owner in r)) r[owner] = {}; 
     for (var character in v[i][owner]) 
     r[owner][character] = v[i][owner][character]; 
    } 
    } 
    return r; 
} 

這應返回你問直接的東西,但很難最佳:視圖必須爲Map和Reduce部分存儲大量數據...

相反,我會去,而不降低一個地圖,像這樣:

function(doc) { 
    emit(doc.owner,null); 
} 

這張地圖,與include_docs=true查詢,將返回看起來像這樣的臺詞:

[ 
    { id : 'charid', key : 'playid', doc : { /* character document */ } }, 
    ... 
] 

服務器如果你真的需要,你可以在結果中使用key重新組合球員的角色。結果按key排序,然後按id排序。

您可以使用startkeyendkey這兩個等於玩家標識符來查詢此視圖,以獲取玩家擁有的所有角色。如果您只需要字符標識符,則添加include_docs=false,並且不會發送厚重的doc部分。

+0

我想我會爲這兩種解決方案創建一個文檔設計,並嘗試他們兩個,看看我更喜歡哪一個。非常感謝!! – tjameson 2010-12-13 17:16:43

相關問題