Reputation: 426
I have the following Meteor.js collection:
Game: {
_id: 1,
rounds: {
round: {
number: 1,
players: {
player: {
_id: someId,
cardSelection: someCard
}
player: {
_id: someId2,
cardSelection: someCard2
}
}
}
}
There are some other fields in the collection but these are the important ones. I'm trying to update a player's selection when they click a card. I'm unsure how to do this in MongoDB/Meteor.
So far, I've tried: 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}}
}
);
The problem is that when calling the update, I don't know the rounds position (well I do, its the last round, but the round number changes), and I don't know the player's position inside the Players object inside the Round object.
Any help?
Upvotes: 0
Views: 743
Reputation: 2147
Assuming this structure for a Games
document, you cannot update a player directly using the positional update operator.
{
_id: 1,
rounds: [{
number: 1,
players: [{
_id: 'someId',
cardSelection: 'someCard'
}, {
_id: 'someId2',
cardSelection: 'someCard2'
}]
}, {
number: 2,
players: []
}]
}
From the mongodb docs:
The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value.
It's not as elegant, but you could set the entire players array. Luckily, underscore makes things easy.
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}
});
Alternatively, you could break rounds
into a separate collection.
Upvotes: 1