0

I have a collection that has a 10 x 10 2-d array field. When I update an element in this array, the entire field is sent back to me as changed.

I update one element of array and the entire array is sent back as changed

entire field is changed

Is there a better way to do the update part?

I'm new to noSQL so maybe I just need to rethink my database setup. This would be a little depressing as I love the simplicity of being able to map javascript objects directly to fields in a single collection. I, however, am not willing to lose ~500 bytes of overhead every time I update this thing.

Is there a way to force Meteor to update the client with more fine-grained changes? Or is this a limitation of how Meteor Livequery works?

Thanks!

jjr4826
  • 194
  • 3
  • 12

1 Answers1

2

The problem is that DDP only supports changed messages at the top-level field granularity. With your current structure, any change to a sub-field of squares will result in the entire squares field being transmitted to the client.

One alternative is to store each element of the 2D array as a separate, top-level field. Below is a complete working example using a - character to separate the elements:

var pool2squares = function(pool) {
  var squares = [];

  _.each(pool, function(value, key) {
    var parts = key.split('-');
    if (parts[0] === 'squares') {
      var i = Number(parts[1]);
      var j = Number(parts[2]);
      if (squares[i] == null)
        squares[i] = [];
      squares[i][j] = value;
    }
  });
  return squares;
};

Pools = new Mongo.Collection('pools', {
  transform: function(doc) {
    return _.extend(doc, {squares: pool2squares(doc)});
  }
});

Meteor.startup(function() {
  Pools.insert({
    'squares-0-0': 'a',
    'squares-0-1': 'b',
    'squares-1-0': 'c',
    'squares-1-1': 'd'
  });

  console.log(Pools.findOne().squares);
});

Here we are using a collection transform to add a squares property to each Pool document whenever it's fetched. The above code will print:

[ [ 'a', 'b' ], [ 'c', 'd' ] ]

To update a Pool:

Pools.update(id, {$set: {'squares-3-4': 'hello'}});
David Weldon
  • 63,632
  • 11
  • 148
  • 146