javascript - 层次结构的Meteor数据库设计

标签 javascript mongodb meteor nosql

我是 Meteor 和 Mongo 的新手,我有一些基本的数据库设计问题。

假设我正在制作一款回合制策略游戏,例如 Advance Wars 。我不确定如何构建我的数据。

我做了一个小演示,在 html 中执行此操作:

{{#each chars}}
  <div class='char' style={{get_style}}>
      ...
  </div>
{{/each}}

我在 Template.body 上定义了这个助手:

Template.body.helpers({
  chars: function() {
    return Characters.find({});
  },
  ...
})

当我一次只运行一款游戏时,这效果很好。但当我同时运行多个游戏时,我不确定如何使其工作。

我想一种方法是拥有一个游戏系列。这些游戏中的每一个都引用两个或多个玩家,并且每个玩家可以有一个 Angular 色列表。每个 Angular 色可以有一个 x 和 y 位置。但随后我不确定用什么查询替换 Characters.find({})

我猜它可能类似于Game.findOne({game_id: game_id}).players[player_id].characters。但我不确定这对性能有何影响。每次 Angular 色移动时,Meteor 都会拉下整个游戏对象吗?我真的不明白 Meteor 到底在做什么。

我猜想另一种需要最少更改的可能性是执行诸如 Characters.find({game_id: 123, player_id: 1}) 之类的操作。然后我会将所有游戏中的所有 Angular 色集中到一个大集合中。对我来说,没有将 Angular 色“封装”在游戏下似乎有点奇怪,但也许这就是正确的方法。

实际上,既然我已经写出来了,似乎第二个选项更有意义。我想我会将所有其他内部游戏对象定义为单独的集合。这是解决这个问题的好方法吗?

最佳答案

假设您的收藏中存储的项目看起来像

{
  _id: String,
  started: Date,
  players: [{
    _id: String,
    name: String,
    characters: [{
      _id: String,
      x: Number,
      y: Number
    }, {
      // ...
    }]
  }, {
    // ...
  }]
}

如果您有一个游戏的 _id 并且您需要获取所有玩家及其 Angular 色,您只需这样做

let gameId = 'whatever';
const games = Games.find({
  _id: gameId
});

之后,在 games 中,您将拥有一个光标,可让您迭代单个元素,即您通过 ID 选择的游戏(设计上是唯一的)。

然后,在您的模板中,您可以这样做

<div class="games">
  {{#each games}}
    <h1>{{started}} — game's `started` scalar property.</h1>
    {{#each players}}
      <div class="player" id="{{_id}}">
        <h2 id="{{_id}}">{{name}} — player's name</h2>
        {{#each characters}}
          <h3 id="{{_id}}">{{x}}, {{y}} — coordinates of a character</h3>
        {{/each}}
      </div>
    {{/each}}
  {{/each}}
</div>

注意 _id 如何尊重当前上下文。

执行相同操作的另一种方法是使用普通对象而不是游标,但只有在保证查询结果是单个元素的情况下才应该使用它:

let gameId = 'whatever';
const game = Games.findOne({
  _id: gameId
});

模板看起来会有点不同。由于您有一个普通对象,因此您没有任何可迭代的内容。因此,您可以访问该对象的属性,忽略最顶层的上下文并将其替换为 with block :

<div class="game">
  {{#with game}}
    <h1>{{started}} — game's `started` scalar property.</h1>
    {{#each players}}
      <div class="player" id="{{_id}}">
        <h2 id="{{_id}}">{{name}} — player's name</h2>
        {{#each characters}}
          <h3 id="{{_id}}">{{x}}, {{y}} — coordinates of a character</h3>
        {{/each}}
      </div>
    {{/each}}
  {{/with}}
</div>

请确保您的模板(或整个客户端)订阅了 Games 集合,并且该集合发布在服务器上并返回整个字段集,并且不会查询数据(或者它确实存在,但您可以控制它)。

关于javascript - 层次结构的Meteor数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34216674/

相关文章:

javascript - 我可以在 JavaScript 中查看哪些数据库实现模式?

javascript - Meteor - 选择元素选项加载函数始终返回未定义

deployment - 在 Meteor 部署环境中获取 Meteor 私有(private)文件夹路径

javascript - AWS 上现有 key 出现 NoSuchKey 错误

javascript - 将 e.location 字符串拆分为变量

Javascript/ECMAscript/Spidermonkey : scope vs. 这个?

javascript - 使用 jQuery/JavaScript 加载页面时使元素消失

javascript - NodeJS 中 require 的排序似乎会产生错误

node.js - Nodejs MongoDb 异步回调

javascript - Meteor.js 我怎么知道我的收藏在客户端准备好了