2010-12-13 90 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

相关问题