Meteor.js中的Mongo DB更新查询

时间:2014-08-22 01:51:15

标签: mongodb meteor

我有以下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}}
              }
             );

问题在于,在调用更新时,我不知道轮次的位置(我做的很好,最后一轮,但是轮数改变了),我不知道玩家&# 39;在Round对象内的Players对象内的位置。

任何帮助?

1 个答案:

答案 0 :(得分:1)

假设Games文档的此结构,您无法使用位置更新运算符直接更新播放器。

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

来自mongodb docs

  

位置$运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为$ placeholder的替换是单个值。

它并不优雅,但你可以设置整个玩家阵列。幸运的是,underscore让事情变得简单。

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分成单独的集合。