Запрос обновления Mongo DB в Meteor.js

У меня есть следующая коллекция Meteor.js:

Game: { 
 _id: 1,
 rounds: {
 round: {
 number: 1,
 players: {
 player: {
 _id: someId,
 cardSelection: someCard
 }
 player: {
 _id: someId2,
 cardSelection: someCard2
 }
 }
 }
 }

В коллекции есть и другие поля, но они важны. Я пытаюсь обновить выбор игрока, когда они нажимают на карту. Я не уверен, как это сделать в MongoDB/Meteor.

До сих пор я пробовал: var currentRound = Games.findOne(gameId).rounds.length;

Games.update({_id: gameId,
 "rounds.round": currentRound,
 "rounds.round.$.players": playerId
 }, 
 {$set: 
 {"rounds.$.players.$": {id: playerId, selection: selection}}
 }
 );

Проблема в том, что при вызове обновления я не знаю позицию раундов (ну, я делаю, ее последний раунд, но число раундов меняется), и я не знаю позицию игрока внутри объекта Players внутри раунда объект.

Любая помощь?

1 ответ

Предполагая эту структуру для документа Games, вы не можете обновлять плеер напрямую, используя оператор позиционного обновления.

{
 _id: 1,
 rounds: [{
 number: 1,
 players: [{
 _id: 'someId',
 cardSelection: 'someCard'
 }, {
 _id: 'someId2',
 cardSelection: 'someCard2'
 }]
 }, {
 number: 2,
 players: []
 }]
}

Из документов mongodb:

Оператор positional $ не может использоваться для запросов, которые пересекают более одного массива, таких как запросы, которые пересекают массивы, вложенные в другие массивы, потому что замена для $ placeholder является единственным значением.

Это не так элегантно, но вы можете установить весь массив игроков. К счастью, подчеркивание облегчает задачу.

var game = Games.findOne(gameId);
var currentRound = game.rounds.length;

var round = _.findWhere(game.rounds, {number: currentRound});

// find and modify the affected player
round.players = _.map(round.players, function (player) {
 if (player.id === playerId) {
 player.cardSelection = selection;
 }
 return player;
});

Games.update({
 _id: gameId,
 "rounds.number": currentRound
}, {
 $set: {"rounds.$.players": round.players}
});

Кроме того, вы можете разбить rounds в отдельную коллекцию.

licensed under cc by-sa 3.0 with attribution.