王艳玲 发表于 2018-10-28 08:06:42

写给MongoDB开发者的50条建议Tip9

  本系列文章翻译自《50 Tips and Tricks for MongoDB   Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译一下。一方面加强自己学习的效果,另一方面让大家也一起来体验一下需要我们这些mongodb使用者需要注意的地方。
  首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到合适的词来表达,所以在文章中可能会出现英文原词,或者说有些地方的翻译会有些生   硬,也就是说会出现直译的地方。翻译该书的主要目的是为大家学习探讨用的,如果有翻译不精准的地方,或者说有更加精准的翻译,还请大家指出,我会及时的更正的,在此先谢过各位了。
  Tip9.Store embedded information in arrays for anonymous access

  将通用化的信息使用嵌入式结构存储在数组中
  有一个问题,经常会出现。
  “在数组中嵌入信息呢?还是用子文档表示呢?”
  当你精确的知道你要查询的内容的时候,适合使用子文档。如果你对于要查询的内容知道的不很精确,适合使用数组。当你知道你要查询的数据的一些规则的时候,适合使用数组。
  假设我们正在开发一个游戏程序,游戏角色可以装备各种武器,我们定义下面的文档。
  


[*]{
[*]"_id":"fred",
[*]"items":{
[*]    "slingshot":{
[*]      "type":"weapon",
[*]      "damage":23,
[*]      "ranged":true
[*]    },
[*]    "jar":{
[*]      "type":"container",
[*]      "contains":"fairy"
[*]    },
[*]    "sword":{
[*]      "type":"weapon",
[*]      "damage":30,
[*]      "ranged":false
[*]    }
[*]}
[*]}
  

  现在,让我们找出所有武器中,能造成20以上伤害的武器。我们发现做不到!子文档的形式不允许我们进入items,告诉它返回伤害值大于等于20的武器。我们只能一个子文档一个子文档的查找,slingshot的伤害是否大于等于20,sword的伤害是否大于等于20。
  如果你想要不使用标识就可以直接访问items,你就应该把他们存放在一个数组中。
  


[*]{
[*]"_id":"fred",
[*]"items":[
[*]    { "id":"slingshot",
[*]      "type":"weapon",
[*]      "damage":23,
[*]      "ranged":true
[*]    },
[*]    { "id":"jar",
[*]      "type":"container",
[*]      "contains":"fairy"
[*]    },
[*]    { "id":"sword",
[*]      "type":"weapon",
[*]      "damage":30,
[*]      "ranged":false
[*]    }
[*]]
[*]}
  

  现在你可以使用查询
  


[*]{"items.damage":{"$gt":20}}
  

  来获取伤害大于等于20的武器了,如果你需要匹配特定项的话,可以使用$elemMatch来匹配。
  那么,什么时候又需要用子文档替代数组呢?当你知道你访问的文档的字段的名称的时候。
  例如,你跟踪一个游戏角儿的能力值,力量,智力,智慧,敏捷,体质和魅力的时候。你肯定想要知道一项具体的能力信息。我们就按照下面的方式存储。
  


[*]{
[*]"id":"fred",
[*]"race":"gnome",
[*]"class":"illusionlist",
[*]"abilities":{
[*]    "str":20,
[*]    "int":30,
[*]    "wis":50,
[*]    "dex":24,
[*]    "con":36,
[*]    "cha":22
[*]}
[*]}
  

  当你需要知道一项特殊技能的值的时候,你就可以查询abilities.str,或者是abilities.wis就可以了。我们不会有“能力值大于20的能力”这样的需求出现,我们总是知道我们要找的是什么。


页: [1]
查看完整版本: 写给MongoDB开发者的50条建议Tip9