Updating dynamic fields and nested arrays in MongoDB

Published on

Let’s take a simple example: a TicTacToe gamefield saved as a nested array in MongoDB.

In the Collection a gamefield document has the following structure:

{
	"_id" : ObjectId("5316267e427d71bf192dce61"),
	"board" : [
		[
			"",
			"",
			""
		],
		[
			"",
			"",
			""
		],
		[
			"",
			"",
			""
		]
	]
}

Nothing special here.

But here comes the challenge:

How would you update the field board[1][2]

##The dot-notation

Check the reference for more info.

There is still a small issue after having discovered the documentation that seemed to save my day: I needed a dynamic string, not a hardcoded one.

So this wasn’t working, sadly, it would throw an error because dear Mongo tries to access to an undefined index ‘x’ and of this undefined index the key y:

gamesColl.update({_id: realId},{
	$set: {
		"board.x.y" : "X"
	}
}, callback);

And I tried this one afterwards, but it isn’t a valid object, of course:

gamesColl.update({_id: realId},{
	$set: {
		"board."+x+"."+y : "X"
	}
}, callback);

And yes, I tried to create the string outside of the update function. This would obviously not work because it sets the field “dotNotationString” to “X” instead:

var dotNotationString = "board."+ x +"." + y;
gamesColl.update({_id: realId},{
	$set: {
		dotNotationString : "X"
	}
}, callback);

Dynamic dot-notation (workaround)

Then it hit me:

var setObject = {};
setObject["board."+ x +"."+ y] = player;
gamesColl.update({_id: realId},{
	$set:setObject
}, function(err,doc){
	console.log(err,doc);
});


PS: I’m not sure if I was really dumb and tired, but I found this to be the only practical solution to my (drinking) problem.

Here, have a slice of pizza 🍕