Search code examples
mongodbmeteorminimongo

Meteor 1.0 - MinimongoError: can't append to array using string field name [-1]


Meteor 1.0 is built for MongoDB v2.4, which doesn't have the $position API that was introduced in Mongo 2.6. Therefore, I'm unable to add array item(s) to the beginning of a MongoDB array as such:

{
  $push: {
    <field>: {
       $each: [ <value1>, <value2>, ... ],
       $position: 0
    }
  }
}

I've tried adding items to the front of a MongoDB array via a workaround...

collectionName.update(
  {_id: 'Xjfb2bbsyj2maFu'},
  {$set:
    {'field.-1': data}
  }
);

... but this only works on server-side code and cannot be interpreted by MiniMongo:

I20141109-23:32:42.382(-5)? Error in oplog callback MinimongoError: can't append to array using string field name [-1]
I20141109-23:32:42.382(-5)?     at MinimongoError (packages/minimongo/minimongo.js:53)
I20141109-23:32:42.383(-5)?     at findModTarget (packages/minimongo/modify.js:133)
I20141109-23:32:42.383(-5)?     at packages/minimongo/modify.js:56
I20141109-23:32:42.383(-5)?     at Function._.each._.forEach     (packages/underscore/underscore.js:113)
I20141109-23:32:42.383(-5)?     at packages/minimongo/modify.js:43
I20141109-23:32:42.383(-5)?     at Function._.each._.forEach (packages/underscore/underscore.js:113)
I20141109-23:32:42.383(-5)?     at Function.LocalCollection._modify (packages/minimongo/modify.js:36)
I20141109-23:32:42.383(-5)?     at packages/mongo/oplog_observe_driver.js:597
I20141109-23:32:42.384(-5)?     at Object.Meteor._noYieldsAllowed (packages/meteor/fiber_helpers.js:11)
I20141109-23:32:42.384(-5)?     at _.extend._handleOplogEntrySteadyOrFetching (packages/mongo/oplog_observe_driver.js:545)

What workaround exists to add items to the beginning of a MongoDB array that is compatible with Meteor 1.0 / MiniMongo?


Solution

  • Do you need atomicity? If not, just modify then $set the entire array.

    var doc = collectionName.findOne();
    doc.arr.unshift('newElement');
    collectionName.update(doc._id, {$set: {'arr': doc.arr}});
    

    Otherwise, sounds like you'll need to do it in server-side code for now.