Node.js Mongoose .update with ArrayFilters

As it stands, I am able to get this functionality working using the Mongo shell, but having issues with the nested arrays inside of Node.js using Mongoose.

Mongo shell command that is successful:

db.test.update({}, {$set: {"this.$[i].that.$[x].amnt": 10000}}, {arrayFilters: [{"i._id": ObjectId('5a568059bc44142a9ca33d09')}, {"x.userId": ObjectId('5a466acb864c752f8c9890c6')}]})

Result: changed the amnt field to 10000. There was no matches returned until calling ObjectId('') on the given strings pulled from the database.

Node.js code:

var conditions = {}
var update = {$set: {"this.$[i].that.$[x].amnt": 1000}
var options = {arrayFilters: [{"i._id": weekId}, {"x.userId":  r.userId}]}

myModel.update(conditions, update, options, function(err, rowsAffected){
    // handler 

Result: { ok: 0, n: 0, nModified: 0 }

_id and userId are schema.Types.ObjectId in the schema for the model.

I tried updating the node_modules/mongodb with the latest files for 3.6.1. It appears mongoose uses 3.0.1. Printing out to console typeof(weekId) or typeof(r.userId) shows type of string. I believe this gets changed based on the schema, but either way I tried calling mongoose.Types.ObjectId(weekId) on these items to see if this resolved it, but no luck.

MongoDB: 3.6.1 Mongoose: 5.0.0-rc2

1 answer

  • answered 2018-01-12 04:58 actraiser

    I don't know if Mongoose 5.0.0 is supposed to support Arrayfilters out of the box but you can achieve it by using Mongoose's command-method which directly executes on MongoDB, hence can utilize all features available which includes ArrayFilters on MongoDB 3.6.1


      update: <YourModel>,
      updates: [
          q: { 'field1.field2._id': mongoose.Types.ObjectId(<someObjectid>) },
          u: {
            $set: { 'field1.$.field2.$[field].fieldToUpdate': "updated!" },
          arrayFilters: [
            { 'field._id': mongoose.Types.ObjectId(<someObjectid>) },