2015-12-11 3 views
0

Я новичок в Meteor и Mongo, и у меня есть некоторые базовые вопросы проектирования баз данных.Дизайн базы данных Meteor для иерархической структуры

Предположим, что я делаю пошаговую стратегическую игру, такую ​​как Advance Wars. Я не уверен, как структурировать свои данные.

Я сделал небольшой демо, где я сделал это в моем HTML:

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

И я этот помощник определен на Template.body:

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

Это прекрасно работает, когда у меня есть только один игра работает одновременно. Но я не уверен, как сделать эту работу, когда у меня есть несколько игр, работающих одновременно.

Я предполагаю, что один из способов сделать это - иметь коллекцию Игр. Каждая из этих Игр ссылается на двух или более игроков и каждого Игрока может иметь список символов. Каждый символ может иметь положение x и y. Но тогда я не уверен, какой запрос я бы заменил Characters.find({}).

Я думаю, это может быть что-то вроде Game.findOne({game_id: game_id}).players[player_id].characters. Но я не уверен, что последствия производительности там. Будет ли Метеор сбрасывать весь игровой объект каждый раз, когда движется персонаж? Я не совсем понимаю, что делает Метеор под капотом.

Я предполагаю, что другая возможность, которая потребует минимальных изменений, - сделать что-то вроде Characters.find({game_id: 123, player_id: 1}). И тогда у меня будут все персонажи из всех игр в одной большой коллекции. Мне кажется странным, что у меня нет персонажей, «инкапсулированных» под Игры, но, возможно, это путь.

Фактически, теперь, когда я написал это, кажется, что второй вариант имеет больше смысла. И я думаю, что я бы определил все другие внутренние игровые объекты как отдельные коллекции. Это хороший способ обойти это?

ответ

1

Давайте представим, что ваша коллекция хранит вещи, которые выглядят как

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

Если у вас есть _id из игры, и вы должны получить все игроки и их характеры, вы просто

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

После этого в games у вас есть курсор, который позволит вам перебирать один элемент, игру, которую вы выбрали по ее идентификатору (который уникален по дизайну).

Затем, в шаблоне, вы

<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 блока:

<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 коллекции, и эту коллекцию публикуется на сервере и возвращает весь набор полей и не запрашивает данные (или делает это, но вы его контролируете).

Смежные вопросы