具有嵌套子文档的此架构是否会破坏性能?

时间:2014-08-31 07:17:48

标签: mongodb meteor

我正在构建一个基于回合制的基于浏览器的RPG,并构建了一个下面举例说明的数据模型。当玩家参与战斗时,读取和写入都将执行“灵魂”和“项目”子文档(数组),并进一步读取“技能”和“角色”子文档。我想这些阵列中的每一个都在1-30个子文档之间发出

我试图在一个集合中包含几乎所有逻辑以提高性能,但是我对嵌套做了太多了吗?

我听说MongoDB / MeteorJS在使用嵌套数组时表现不佳,并希望就这个数据模型是否可行获得一些意见?

    email: 'a@test'
    password: 'f321'
    profile:
      character: 
        _id: 'c001'
        location: 'Isenheim'
        name: 'Ugyr'
        race: 'human'
        level: 1
        experience: 1
        maxHealth: 10
        curHealth: 10
        curAp: 10
        maxAp: 10
        flagged: false
        gold: 0
        souls: [
          _id: 'S001'
          name: 'Hound'
          race: 'beast'
          cost: 5
          active: false
          maxHealth: 5
          curHealth: 5
          maxAp: 6
          curAp: 6
          skills: [
            name: 'Bite'
            damage: 1
            cost: 2
          ,
            name: 'Shred'
            damage: 2
            cost: 4
            effects: 
              name: 'Bleeding'
              duration: 2
              type: 'subtractive'
              stats: ['curHealth']
              value: 1
          ]
        ]
        skills: [
          name: 'Slash'
          type: 'direct'
          damage: 2
          cost: 2
        ,
          name: 'Pierce'
          type: 'direct'
          damage: 3
          cost: 3
        ,
          name: 'Throwing Knives'
          type: 'direct'
          damage: 1
          cost: 1
        ]
        items: 
          equiped: 
            weapon:
              name: 'Rusty Knife' 
              attack: 2
            shield: null

          inventory: [
            name: 'Potion'
            type: 'consumable'
            effects:
              type: 'additive'
              stats: ['curHealth', 'curAp']
              value: 3
            amount: 500
          ,
            name: 'Minor Soul Stone'
            type: 'consumable'
            amount: 500
            effects: [
              type: 'additive'
              stats: ['curAp']
              value: 2
            ,
              type: 'subtractive'
              stats: ['curHealth']
              value: 1
            ]
          ,
            name: 'Health Potion'
            type: 'consumable'
            amount: 100
            effects: [
              type: 'additive'
              stackable: false
              stats: ['curHealth']
              value: 1
              duration: 2
            ]
          ]
          conditions: [

          ]

1 个答案:

答案 0 :(得分:5)

是的,你在筑巢方面做得太过分了。

Meteor DDP仅发送第一级属性的更改/差异。因此对souls& items将等同于再次发送的整个profile

我建议将charactersoulsitems一起分成单独的集合。

然后,对所有这些进行非规范化userId并一次性发布,例如:

Meteor.publish("my-characters",function(){
  if (this.userId == null){
    return;
  }
  return [
    characters.find({"userId": this.userId}),
    characterSouls.find({"userId": this.userId}),
    characterItems.find({"userId": this.userId})
  ];
});

这可能会在发布游标和广告方面提供最佳表现。数据 - 上的线。

另外,不要忘记在userId上编制索引:

characters._ensureIndex({userId: 1});
characterSouls._ensureIndex({userId: 1});
characterItems._ensureIndex({userId: 1});